1 集群安全升級
1.1 環(huán)境安全
1.1.1 CIS基礎
學習目標
這一節(jié),我們從 基準測試、基準手冊、小結 三個方面來學習
基準測試
簡介
基準測試是指通過設計科學的測試方法、測試工具和測試系統(tǒng),實現(xiàn)對一類測試對象的某項性能指標進行定量的和可對比的測試,其目的是確認當前的資源能力是否能夠滿足項目程序的需求。
比如:
- 對計算機CPU進行浮點運算的基準測試了解CPU的運算性能
- 對計算機CPU進行數(shù)據(jù)帶寬的基準測試了解CPU的作業(yè)吞吐能力
- 對數(shù)據(jù)庫系統(tǒng)的ACID性能指標進行基準測試確認需求的數(shù)據(jù)庫系統(tǒng)
- ...
可測量、可重復、可對比是基準測試的三大原則:
- 可測量是指測試的輸入和輸出結果可以測試具體數(shù)據(jù)
- 可重復是指測試的過程一致其測試實現(xiàn)的結果不受影響
- 可對比是指測試對象的結果具有可預測的比對關系
CIS
CIS(Center for internet Security)是一個非營利性組織,成立于2000年10月。CIS由一個全球IT社區(qū)驅動,其共同目標是識別、開發(fā)、驗證、推廣和維持網(wǎng)絡防御的最佳實踐解決方案。多年來,CIS已經(jīng)為各種規(guī)模的企業(yè)制作并發(fā)布了一些免費的工具和解決方案,旨在加強他們的網(wǎng)絡安全準備。
CIS控制措施提供了一個按優(yōu)先順序排列的清單,企業(yè)可以通過實施該清單來大大減少其網(wǎng)絡攻擊面。CIS基準在為更好的安全系統(tǒng)配置提出建議時參考了這些控制措施,這些基準都會經(jīng)歷初審和復審兩個階段的共識評審,如果沒有問題的話,就會納入基準中,然后進行推廣。
參考資料:https://www.cisecurity.org/
CIS基準
CIS基準由Internet安全中心發(fā)布的一系列與安全相關的最佳實踐的集合,它涉及安全配置IT系統(tǒng)、軟件、網(wǎng)絡和云基礎設施等內(nèi)容。隨著安全專家的不斷識別、完善和驗證安全最佳實踐,CIS基準擴展至數(shù)百項,涵蓋了七個核心技術類別。
操作系統(tǒng)基準
- 描述了如何安全地配置各類主流操作系統(tǒng)。包括訪問管理、驅動程序安裝等。
服務器軟件基準
- 描述如何安全的配置各類主流服務器軟件的安全配置。包括證書、API 設置和服務器管理等。
云提供商基準
- 描述了如何安全配置常見公共云的安全最佳實踐。包括訪問控制、日志管理、安全審計等。
移動設備基準
- 描述了如何安全配置常見移動設備配置。包括屬性設置、應用權限和隱私配置等。
網(wǎng)絡設備基準
- 描述了如何安全配置各類常見網(wǎng)絡設備。
桌面軟件基準
- 描述了如何安全配置和使用應用程序的安全最佳實踐。包括郵件隱私、瀏覽器設置等。
多功能打印設備基準
- 描述了配置和保護多功能打印機的最佳實踐,例如固件更新管理、無線網(wǎng)絡訪問配置等。
Kubernetes CIS 基準測試
Kubernetes 雖然作為一個出色的容器任務編排領域的管理平臺,但其整體安全性隱患在不斷的版本迭代過程中一直存在,雖然版本的迭代解決了一部分安全隱患,但是也暴露了更多的潛在隱患。所以自從2017 年,CIS 一直致力于保護 Kubernetes,并且推出了一系列的CIS基準。
Kubernetes CIS 基準與其他 CIS 基準一樣,提供針對 Kubernetes 及其容器的獨特需求量身定制的安全狀態(tài)管理最佳實踐。Kubernetes 的 CIS 基準主要體現(xiàn)在兩個方面:
- 主節(jié)點安全配置:涵蓋調度程序、控制器管理器、配置文件、etcd 和 PSP等
- 工作節(jié)點安全配置:針對 Kubelet 和配置文件。
參考資料:https://www.cisecurity.org/benchmark/kubernetes/
基準手冊
簡介
CIS提供了一系列與安全配置有關系的策略規(guī)則,這些規(guī)則會根據(jù)軟件、平臺等進行分門別類的方式進行管理,我們可以進行相關規(guī)則策略文件的下載,然后進行相關的查看。
參考資料:https://www.cisecurity.org/cis-benchmarks/
K8s CIS手冊
CIS官方為kubernetes提供了大量的安全性規(guī)則配置,目前最后一次更新是 2022年8月。
參考資料: https://www.cisecurity.org/benchmark/kubernetes
相關文件的下載頁面: https://downloads.cisecurity.org/#/
注意:
這里提供了多種kubernetes平臺的檢測基準規(guī)則,我們這里選則合適的規(guī)則。
以 v1.23 為例,查看文件的目錄結構
小結
1.1.2 測試工具
學習目標
這一節(jié),我們從 工具簡介、工具解析、小結 三個方面來學習
工具簡介
簡介
CIS不僅僅提供了大量環(huán)境中與安全相關的配置策略,我們可以結合配置文件中的詳細條目一條一條的進行手工設置,因為這種配置方式和檢測方式比較繁瑣,所以很多廠商也針對CIS的規(guī)則提供了大量安全配置相關的檢測工具。針對kubernetes來說,Aquq廠商就退出了一款K8s的CIS檢測工具 Kube-bench,它以k8s的CIS規(guī)則為基準,通過自動化的方式來檢測k8s的相關默認規(guī)則是否滿足要求,然后將不安全的配置參數(shù)、敏感的文件權限等提示出來,方便人們進行相關的檢測和查看。
kube-bench 的基本信息
github地址:https://github.com/aquasecurity/kube-bench
最新版本:0.6.9(20220809)
關于kube-bench 和 CSI的版本對應關系
https://github.com/aquasecurity/kube-bench/blob/main/docs/platforms.md#cis-kubernetes-benchmark-support
工具部署
獲取軟件
mkdir /data/softs && cd /data/softs
wget https://github.com/aquasecurity/kube-bench/releases/download/v0.6.9/kube-bench_0.6.9_linux_amd64.tar.gz
部署軟件
tar -zxvf kube-bench_0.6.9_linux_amd64.tar.gz
mv kube-bench /usr/sbin/
配置定制
mkdir /etc/kube-bench
mv cfg /etc/kube-bench/
查看默認的檢測基準文件目錄 -- 包括了所有的cis版本的基準配置
# ls /etc/kube-bench/cfg/
ack-1.0 aks-1.0 cis-1.20 cis-1.23 cis-1.5 cis-1.6 config.yaml eks-1.0.1 gke-1.0 gke-1.2.0 rh-0.7 rh-1.0
注意:
不同的kube-bench 針對不同的平臺各有版本的對應關系,不同的平臺會用 /etc/kube-bench/cfg/目錄下的各自版本目錄的配置檢測文件,這是由config.yaml文件來決定的
查看一個cis基準目錄結構
# tree /etc/kube-bench/cfg/cis-1.23/
/etc/kube-bench/cfg/cis-1.23/
├── config.yaml 當前檢測入口
├── controlplane.yaml 控制平面檢測
├── etcd.yaml etcd數(shù)據(jù)檢測
├── master.yaml master節(jié)點配置檢測
├── node.yaml node節(jié)點配置檢測
└── policies.yaml 策略配置檢測
0 directories, 6 files
工具解析
命令幫助
查看幫助命令
# kube-bench --help
This tool runs the CIS Kubernetes Benchmark (https://www.cisecurity.org/benchmark/kubernetes/)
Usage:
kube-bench [flags]
kube-bench [command]
Available Commands:
completion Generate the autocompletion script for the specified shell
help Help about any command
run Run tests 執(zhí)行測試
version Shows the version of kube-bench.
Flags:
...
--config string config file (default is ./cfg/config.yaml)
-D, --config-dir string config directory (default "/etc/kube-bench/cfg")
...
Use "kube-bench [command] --help" for more information about a command.
注意:
不同版本的kube-bench的命令參數(shù)和操作可能會出現(xiàn)比較大的調整
查看執(zhí)行測試的命令幫助
# kube-bench run --help
Run tests. If no arguments are specified, runs tests from all files
Usage:
kube-bench run [flags]
Flags:
-h, --help help for run
-s, --targets strings Specify targets of the benchmark to run. These names need to match the filenames in the cfg/<version> directory.
For example, to run the tests specified in master.yaml and etcd.yaml, specify --targets=master,etcd
If no targets are specified, run tests from all files in the cfg/<version> directory.
Global Flags:
--alsologtostderr log to standard error as well as files
--asff Send the results to AWS Security Hub
--benchmark string Manually specify CIS benchmark version. It would be an error to specify both --version and --benchmark flags
-c, --check string A comma-delimited list of checks to run as specified in CIS document. Example --check="1.1.1,1.1.2"
--config string config file (default is ./cfg/config.yaml)
-D, --config-dir string config directory (default "/etc/kube-bench/cfg")
--exit-code int Specify the exit code for when checks fail
-g, --group string Run all the checks under this comma-delimited list of groups. Example --group="1.1"
--include-test-output Prints the actual result when test fails
--json Prints the results as JSON
--junit Prints the results as JUnit
--log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0)
--log_dir string If non-empty, write log files in this directory
--logtostderr log to standard error instead of files (default true)
--noremediations Disable printing of remediations section
--noresults Disable printing of results section
--nosummary Disable printing of summary section
--nototals Disable printing of totals for failed, passed, ... checks across all sections
--outputfile string Writes the results to output file when run with --json or --junit
--pgsql Save the results to PostgreSQL
--scored Run the scored CIS checks (default true)
--skip string List of comma separated values of checks to be skipped
--stderrthreshold severity logs at or above this threshold go to stderr (default 2)
--unscored Run the unscored CIS checks (default true)
-v, --v Level log level for V logs
--version string Manually specify Kubernetes version, automatically detected if unset
--vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging
命令補全
定制環(huán)境屬性
echo 'source <(kube-bench completion bash)' >> /root/.bashrc
重載環(huán)境配置
source /root/.bashrc
檢測測試
執(zhí)行完整測試
# kube-bench run
[INFO] 1 Control Plane Security Configuration
[INFO] 1.1 Control Plane Node Configuration Files
[PASS] 1.1.1 Ensure that the API server pod specification file permissions are set to 644 or more restrictive (Auto
mated)
...
[INFO] 1.2 API Server
[WARN] 1.2.1 Ensure that the --anonymous-auth argument is set to false (Manual)
...
[INFO] 1.4 Scheduler
[FAIL] 1.4.1 Ensure that the --profiling argument is set to false (Automated)
...
== Summary total ==
67 checks PASS
12 checks FAIL
46 checks WARN
0 checks INFO
結果顯示:
這里面顯示的測試順序與CSI的策略文檔目錄完全一致
檢測結果狀態(tài)有:INFO-提示,PASS-通過,WARN-警告,F(xiàn)AIL-失敗
指定目標進行檢測
# kube-bench run --targets node
[INFO] 4.2 Kubelet
[PASS] 4.2.1 Ensure that the --anonymous-auth argument is set to false (Automated)
...
[FAIL] 4.2.6 Ensure that the --protect-kernel-defaults argument is set to true (Automated)
...
[WARN] 4.2.9 Ensure that the --event-qps argument is set to 0 or a level which ensures appropriate event capture (Manual)
...
== Summary total ==
19 checks PASS
1 checks FAIL
3 checks WARN
0 checks INFO
小結
1.1.3 組件測試
學習目標
這一節(jié),我們從 原理解讀、簡單實踐、小結 三個方面來學習
原理解讀
檢測入口
基本目錄結構
# ls /etc/kube-bench/cfg/
ack-1.0 aks-1.0 cis-1.20 cis-1.23 cis-1.5 cis-1.6 config.yaml eks-1.0.1 gke-1.0 gke-1.2.0 rh-0.7 rh-1.0
# tree /etc/kube-bench/cfg/cis-1.23/
/etc/kube-bench/cfg/cis-1.23/
├── config.yaml 當前檢測入口,如果與cfg目錄下的config.yaml文件有重復的話,會覆蓋
├── controlplane.yaml 控制平面檢測
├── etcd.yaml etcd數(shù)據(jù)檢測
├── master.yaml master節(jié)點配置檢測
├── node.yaml node節(jié)點配置檢測
└── policies.yaml 策略配置檢測
0 directories, 6 files
注意:
這里的文件是按照CSI的文件結構來進行劃分的功能基準測試
# for i in $(ls /etc/kube-bench/cfg/cis-1.23); do echo "-----$i-----"; sed -n '4,6p' $i; done
-----config.yaml-----
-----controlplane.yaml-----
id: 3
text: "Control Plane Configuration"
type: "controlplane"
-----etcd.yaml-----
id: 2
text: "Etcd Node Configuration"
type: "etcd"
-----master.yaml-----
id: 1
text: "Control Plane Security Configuration"
type: "master"
-----node.yaml-----
id: 4
text: "Worker Node Security Configuration"
type: "node"
-----policies.yaml-----
id: 5
text: "Kubernetes Policies"
type: "policies"
查看kube-bench的檢測入口
# cat /etc/kube-bench/cfg/config.yaml
---
## Controls Files.
# These are YAML files that hold all the details for running checks.
#
## Uncomment to use different control file paths.
# masterControls: ./cfg/master.yaml
# nodeControls: ./cfg/node.yaml
master:
components: # master檢測的組件
- apiserver
- scheduler
- controllermanager
- etcd
- flanneld
# kubernetes is a component to cover the config file /etc/kubernetes/config that is referred to in the benchmark
- kubernetes
- kubelet
kubernetes: # 默認的配置文件
defaultconf: /etc/kubernetes/config
apiserver:
bins: # 服務執(zhí)行用到的命令
- "kube-apiserver"
...
confs: #組件用到的配置文件
- /etc/kubernetes/manifests/kube-apiserver.yaml
...
defaultconf: /etc/kubernetes/manifests/kube-apiserver.yaml
scheduler:
bins:
...
confs:
...
defaultconf: /etc/kubernetes/manifests/kube-scheduler.yaml
kubeconfig: # 組件通信用到的認證文件
- /etc/kubernetes/scheduler.conf
...
defaultkubeconfig: /etc/kubernetes/scheduler.conf
controllermanager:
...
etcd:
...
flanneld:
...
kubelet:
...
node:
...
etcd:
...
controlplane:
...
policies:
...
managedservices:
components: []
version_mapping:
...
"1.23": "cis-1.23"
...
target_mapping:
...
"cis-1.23":
- "master"
- "node"
- "controlplane"
- "etcd"
- "policies"
...
檢測時候涉及到的一些屬性配置
master節(jié)點啟動涉及到的屬性信息
https://kubernetes.io/zh-cn/docs/reference/command-line-tools-reference/kube-apiserver/
node節(jié)點啟動涉及到的屬性信息
https://kubernetes.io/zh-cn/docs/reference/command-line-tools-reference/kubelet/
etcd服務啟動涉及到的屬性信息
/etc/kubernetes/manifests/etcd.yaml
簡單實踐
檢測規(guī)則
查看檢測文件
# head -n24 /etc/kube-bench/cfg/cis-1.23/master.yaml
---
controls:
version: "cis-1.23"
# CSI規(guī)則組的規(guī)則編號
id: 1
# 規(guī)則檢測的提示信息
text: "Control Plane Security Configuration"
# 該規(guī)則歸屬的檢測類型
type: "master"
# 規(guī)則組條目信息
groups:
# 規(guī)則組條目編號
- id: 1.1
# 規(guī)則檢測的提示信息
text: "Control Plane Node Configuration Files"
checks: # 執(zhí)行檢測的規(guī)則
# 執(zhí)行檢測的規(guī)則編號
- id: 1.1.1
# 規(guī)則檢測的提示信息
text: "Ensure that the API server pod specification file permissions are set to 644 or more restrictive (Automated)"
# 規(guī)則檢測命令
audit: "/bin/sh -c 'if test -e $apiserverconf; then stat -c permissions=%a $apiserverconf; fi'"
# 檢測項目
tests:
# 檢測的內(nèi)容
test_items:
- flag: "permissions"
# 檢測的對比結果標準值
compare:
op: bitmask
value: "644"
# 推薦的修復方案
remediation: |
Run the below command (based on the file location on your system) on the
control plane node.
For example, chmod 644 $apiserverconf
# 確定對比的結果,如果檢測檢測結果值為true,則顯示檢測通過PASS,否則顯示檢測失敗FAIL
# 如果檢測檢測結果值為false,則表示檢測無法通過,顯示檢測異常WARN
scored: true
# 此處還有一個擴展屬性 type
# type: manual(默認) | skip(跳過檢測,顯示INFO)
確認效果
確認檢查失敗的條目
# kube-bench run -s master | grep FAIL
[FAIL] 1.1.12 Ensure that the etcd data directory ownership is set to etcd:etcd (Automated)
[FAIL] 1.2.6 Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated)
[FAIL] 1.2.18 Ensure that the --profiling argument is set to false (Automated)
...
以1.2.18檢測失敗的規(guī)則為例,查看規(guī)則內(nèi)容
# vim /etc/kube-bench/cfg/cis-1.23/master.yaml
...
- id: 1.2.18
text: "Ensure that the --profiling argument is set to false (Automated)"
audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep"
tests:
test_items:
- flag: "--profiling"
compare:
op: eq
value: false
remediation: |
Edit the API server pod specification file $apiserverconf
on the control plane node and set the below parameter.
--profiling=false
scored: true
確認當前的kube-apiserver的啟動參數(shù)
grep 'profiling' /etc/kubernetes/manifests/kube-apiserver.yaml
查找異常檢測條目的修復方案中的屬性信息
--profiling 默認值:true
通過 Web 接口 host:port/debug/pprof/ 啟用性能分析。
資料來源:
https://kubernetes.io/zh-cn/docs/reference/command-line-tools-reference/kube-apiserver/
根據(jù)修復方案解決該檢測問題
# vim /etc/kubernetes/manifests/kube-apiserver.yaml
...
- command:
- kube-apiserver
- --profiling=false # 增加屬性信息
...
稍等5秒,當前kube-apiserver服務的pod會自動刪除重建,然后使用新的配置
重新檢測查看效果
# kube-bench run -s master | grep '1.2.18'
[PASS] 1.2.18 Ensure that the --profiling argument is set to false (Automated)
結果顯示:
按照修復方案操作后,檢測結果通過了
小結
1.1.4 定制測試
學習目標
這一節(jié),我們從 場景解讀、定制實踐、小結 三個方面來學習
場景解讀
如何看待檢測的失敗條目
注意:
對于一些失敗的檢測條目,不是說一定要進行修復的,而是需要根據(jù)自己的實際情況來進行調整。
遇到一些不太了解的錯誤條目,可以查看CSI基準測試文件或者查看k8s的官網(wǎng)
重點關注:
有些參數(shù)是在config文件中才會生效,有些能在命令啟動參數(shù)中生效
如何看待不影響環(huán)境的錯誤測試條目
對于一些錯誤檢測條目應該如何處理?
1 無視 - 不做任何處理
2 不檢查 - 更改檢測配置文件即可
3 忽略 - 修改配置文件后自動忽略該規(guī)則
屬性解析
在執(zhí)行檢測規(guī)則條目中有兩條屬性可以進行設定檢測的結果變化
# 確定檢測的預期結果
# 如果檢測檢測結果值為true,則顯示檢測通過PASS,否則顯示檢測失敗FAIL
# 如果檢測檢測結果值為false,則表示檢測無法通過,顯示檢測異常WARN
scored: true
# 此處還有一個擴展屬性 type
type: manual(默認) | skip(跳過檢測,顯示INFO)
在執(zhí)行檢測的規(guī)則中存在提示信息屬性,如果該屬性的信息我看不懂的話,可以定制為中文提示
text: 檢測規(guī)則的信息
remediation: 修復方案的信息
定制實踐
查看待檢測效果
查看待檢測效果
# kube-bench run -s master
...
[FAIL] 1.3.2 Ensure that the --profiling argument is set to false (Automated)
...
1.3.2 Edit the Controller Manager pod specification file /etc/kubernetes/manifests/kube-controller-manager.yaml
on the control plane node and set the below parameter.
--profiling=false
...
實踐1 - 信息提示修改為中文
修改規(guī)則
# vim /etc/kube-bench/cfg/cis-1.23/master.yaml
...
- id: 1.3.2
text: "確保 --profiling 的屬性參數(shù)為false (自動檢測)"
audit: "/bin/ps -ef | grep $controllermanagerbin | grep -v grep"
tests:
test_items:
- flag: "--profiling"
compare:
op: eq
value: false
remediation: |
在控制節(jié)點編輯 Controller Manager pod 的配置文件 $controllermanagerconf
按照 --profiling=false 方式修改
scored: true
...
重新檢測效果
# kube-bench run -s master
...
[FAIL] 1.3.2 確保 --profiling 的屬性參數(shù)為false (自動檢測)
...
1.3.2 在控制節(jié)點編輯 Controller Manager pod 的配置文件 /etc/kubernetes/manifests/kube-controller-manager.yaml
按照 --profiling=false 方式修改
...
實踐2 - 失敗檢測信息修改為警告
修改規(guī)則
# vim /etc/kube-bench/cfg/cis-1.23/master.yaml
...
- id: 1.3.2
...
scored: false
...
重新檢測效果
# kube-bench run -s master
...
[WARN] 1.3.2 確保 --profiling 的屬性參數(shù)為false (自動檢測)
結果顯示:
告警信息修改為了 警告模式
實踐3 - 失敗檢測信息修改為提示,不進行檢測直接通過
修改規(guī)則
# vim /etc/kube-bench/cfg/cis-1.23/master.yaml
...
- id: 1.3.2
...
scored: false
type: skip
...
重新檢測效果
# kube-bench run -s master
...
[INFO] 1.3.2 確保 --profiling 的屬性參數(shù)為false (自動檢測)
結果顯示:
告警信息修改為了 提示模式
1.1.5 測試鏡像
學習目標
這一節(jié),我們從 基礎知識、簡單實踐、小結 三個方面來學習
基礎知識
簡介
在后續(xù)的實踐過程中,會涉及到各種場景的測試實踐,為了更好的查看測試的效果,我們這里提前做好一些基準的鏡像。
獲取基礎鏡像
獲取基準鏡像
for i in nginx django tomcat busybox
do
docker pull $i
docker tag $i kubernetes-register.superopsmsb.com/superopsmsb/$i
docker push kubernetes-register.superopsmsb.com/superopsmsb/$i
docker rmi $i
done
創(chuàng)建鏡像構建文件
創(chuàng)建基準目錄
[root@kubernetes-master1 ~]# mkdir /data/images/web/{nginx,tomcat,django} -p
簡單實踐
定制nginx鏡像
準備基準代碼文件
[root@kubernetes-master1 ~]# mkdir /data/images/web/nginx/scripts -p
創(chuàng)建服務啟動文件
[root@kubernetes-master1 ~]# cat /data/images/web/nginx/scripts/startup.sh
#!/bin/bash
# 定制容器里面的nginx服務啟動腳本
# 定制tomcat的首頁內(nèi)容
echo "Hello Nginx, $HOSTNAME-$NGINX_VERSION" > /usr/share/nginx/html/index.html
# 啟動nginx
nginx -g "daemon off;"
定制Dockerfile文件
[root@kubernetes-master1 ~]# cat /data/images/web/nginx/Dockerfile
# 構建一個基于nginx的定制鏡像
# 基礎鏡像
FROM kubernetes-register.superopsmsb.com/superopsmsb/nginx
# 鏡像作者
MAINTAINER shuji@superopsmsb.com
# 添加文件
ADD scripts/startup.sh /data/scripts/startup.sh
# 執(zhí)行命令
CMD ["/bin/bash", "/data/scripts/startup.sh"]
定制構造鏡像
[root@kubernetes-master1 ~]# docker build -t kubernetes-register.superopsmsb.com/superopsmsb/nginx_web:v0.1 /data/images/web/nginx/
測試構造鏡像
[root@kubernetes-master1 ~]# docker run -d --name nginx-test -p 666:80 kubernetes-register.superopsmsb.com/superopsmsb/nginx_web:v0.1
58b84726ff29b87e3c8e6a6489e4bead4d298bdd17ac08d90a05a8ad8674906e
[root@kubernetes-master1 ~]# curl 10.0.0.12:666
Hello Nginx, 58b84726ff29-1.23.0
[root@kubernetes-master1 ~]# docker rm -f nginx-test
nginx-test
提交鏡像到遠程倉庫
[root@kubernetes-master1 ~]# docker push kubernetes-register.superopsmsb.com/superopsmsb/nginx_web:v0.1
定制Django鏡像
準備基準代碼文件
[root@kubernetes-master1 ~]# mv /data/code/blog /data/images/web/django/
[root@kubernetes-master1 ~]# mkdir /data/images/web/nginx/scripts -p
創(chuàng)建服務啟動文件
[root@kubernetes-master1 ~]# cat /data/images/web/django/scripts/startup.sh
#!/bin/bash
# 定制容器里面的django服務啟動腳本
# 定制服務啟動命令
python /data/code/blog/manage.py runserver 0.0.0.0:8000
定制Dockerfile文件
[root@kubernetes-master1 ~]# cat /data/images/web/django/Dockerfile
# 構建一個基于django的定制鏡像
# 基礎鏡像
FROM kubernetes-register.superopsmsb.com/superopsmsb/django
# 鏡像作者
MAINTAINER shuji@superopsmsb.com
# 拷貝文件
ADD blog /data/code/blog
ADD scripts/startup.sh /data/scripts/startup.sh
# 暴露django端口
EXPOSE 8000
# 定制容器的啟動命令
CMD ["/bin/bash", "/data/scripts/startup.sh"]
定制構造鏡像
[root@kubernetes-master1 ~]# docker build -t kubernetes-register.superopsmsb.com/superopsmsb/django_web:v0.1 /data/images/web/django/
測試構造鏡像
[root@kubernetes-master1 ~]# docker run -d --name django-test -p 666:8000 kubernetes-register.superopsmsb.com/superopsmsb/django_web:v0.1
d8f6a1a237f9276917ffc6e233315d02940437f91c64f43894fb3fab8fd50783
[root@kubernetes-master1 ~]# curl 10.0.0.12:666
Hello Django, d8f6a1a237f9 1.10.4
[root@kubernetes-master1 ~]# docker rm -f django-test
nginx-test
提交鏡像到遠程倉庫
[root@kubernetes-master1 ~]# docker push kubernetes-register.superopsmsb.com/superopsmsb/django_web:v0.1
定制Tomcat鏡像
準備基準代碼文件
[root@kubernetes-master1 ~]# mkdir /data/images/web/tomcat/scripts -p
創(chuàng)建服務啟動文件
[root@kubernetes-master1 ~]# cat /data/images/web/tomcat/scripts/startup.sh
#!/bin/bash
# 定制容器里面的tomcat服務啟動腳本
# 定制tomcat的首頁內(nèi)容
echo "Hello Tomcat, $HOSTNAME-$TOMCAT_VERSION" > /usr/local/tomcat/webapps/ROOT/index.jsp
# 啟動tomcat
catalina.sh run
定制Dockerfile
定制Dockerfile文件
[root@kubernetes-master1 ~]# cat /data/images/web/tomcat/Dockerfile
# 構建一個基于tomcat的定制鏡像
# 基礎鏡像
FROM kubernetes-register.superopsmsb.com/superopsmsb/tomcat
# 鏡像作者
MAINTAINER shuji@superopsmsb.com
# 拷貝文件
RUN mv webapps.dist/* webapps/
# 添加文件
ADD scripts/startup.sh /data/scripts/startup.sh
# 執(zhí)行命令
CMD ["/bin/bash", "/data/scripts/startup.sh"]
定制構造鏡像
[root@kubernetes-master1 ~]# docker build -t kubernetes-register.superopsmsb.com/superopsmsb/tomcat_web:v0.1 /data/images/web/tomcat/
測試構造鏡像
[root@kubernetes-master1 ~]# docker run -d --name tomcat-test -p 666:8080 kubernetes-register.superopsmsb.com/superopsmsb/tomcat_web:v0.1
e46eb26c49ab873351219e98d6e236fd0445aa39edb8edb0bf86560a808614fb
[root@kubernetes-master1 ~]# curl 10.0.0.12:666
Hello Tomcat, e46eb26c49ab-10.0.22
[root@kubernetes-master1 ~]# docker rm -f tomcat-test
tomcat-test
提交鏡像到遠程倉庫
[root@kubernetes-master1 ~]# docker push kubernetes-register.superopsmsb.com/superopsmsb/tomcat_web:v0.1
小結
1.2 網(wǎng)絡安全
1.2.1 CNI方案
學習目標
這一節(jié),我們從 基礎原理、方案解讀、小結 三個方面來學習
基礎原理
容器訪問模式
方法1: 虛擬網(wǎng)橋 + 虛擬網(wǎng)卡對
方法2: 多路復用 + 內(nèi)核級的VLAN模塊
方法3: 硬件交換 + 硬件虛擬化
CNI簡介
根據(jù)我們對于容器的基本了解,他雖然可以借助于虛擬網(wǎng)橋docker0實現(xiàn)一定程度的網(wǎng)絡功能,但是在大范圍容器訪問層面,其沒有最好的網(wǎng)絡解決方案,只能借助于一些第三方的網(wǎng)絡解決方案來實現(xiàn)容器級別的跨網(wǎng)絡通信能力。
CNI的全稱是Container Network Interface,Google和CoreOS聯(lián)合定制的多容器通信的網(wǎng)絡模型。在Kubernetes中通過一個CNI接口來替代docker0,它在宿主機上的默認名字叫cni0。它沒有使用Docker的網(wǎng)絡模型的原因有兩個:1 不想被Docker要挾,2 自有的網(wǎng)絡namespace設計有關。
CNI的設計思想即為:Kubernetes在啟動Pod的pause容器之后,直接調用CNI網(wǎng)絡插件,從而實現(xiàn)為Pod內(nèi)部應用容器所在的Network Namespace配置符合預期的網(wǎng)絡信息。這里面需要特別關注兩個方面:
- Container必須有自己的網(wǎng)絡命名空間的環(huán)境,也就是endpoint地址。
- Container所在的網(wǎng)段必須能夠注冊網(wǎng)絡地址信息
對容器網(wǎng)絡的設置和操作都通過插件(Plugin)進行具體實現(xiàn),CNI插件包括兩種類型:CNIPlugin和IPAM(IP Address Management)Plugin。CNI Plugin負責為容器配置網(wǎng)絡資源,IPAM Plugin負責對容器的IP地址進行分配和管理。IPAM Plugin作為CNI Plugin的一部分,與CNI Plugin一起工作。
在Kubernetes中,CNI對于容器網(wǎng)絡的設置主要是以CNI Plugin插件的方式來為容器配置網(wǎng)絡資源,它主要有三種模式:
MainPlugin
- 用來創(chuàng)建具體的網(wǎng)絡設備的二進制文件
- 比如bridge、ipvlan、vlan、host-device
IPAM Plugin
- IPAM 就是 IP Address Management
- 負責對容器的IP地址進行分配和管理,作為CNI Plugin的一部分,與CNI Plugin一起工作
Meta Plugin
- 由CNI社區(qū)維護的內(nèi)部插件功能模塊,常見的插件功能模塊有以下幾種
- flannel 專門為Flannel項目提供的插件
- tuning 通過sysctl調整網(wǎng)絡設備參數(shù)的二進制文件
- portmap 通過iptables配置端口映射的二進制文件
- bandwidth 使用 Token Bucket Filter (TBF)來進行限流的二進制文件
- firewall 通過iptables或者firewalled添加規(guī)則控制容器的進出流量
更多詳情查看:https://github.com/containernetworking/cni/blob/main/SPEC.md
CNI目前被誰管理?
在 Kubernetes 1.24 之前,CNI 插件也可以由 kubelet 使用命令行參數(shù) cni-bin-dir 和 network-plugin 管理。而在Kubernetes 1.24 移除了這些命令行參數(shù), CNI 的管理不再是 kubelet 的工作。而變成下層的容器引擎需要做的事情了,比如cri-dockerd服務的啟動文件
查看服務文件 /etc/systemd/system/cri-docker.service
ExecStart=/usr/local/bin/cri-dockerd --network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin ...
注意:
/opt/cni/bin 目錄是部署kubernetes的時候,安裝的cni-tools軟件包自動創(chuàng)建出來的,這里面包含了很多的網(wǎng)絡命令工具
flannel的CNI配置文件
# cat /etc/cni/net.d/10-flannel.conflist
{
"name": "cbr0",
"plugins": [
{
"type": "flannel", # 為Flannel項目提供的插件,配置容器網(wǎng)絡
"delegate": {
"hairpinMode": true,
"isDefaultGateway": true
}
},
{
"type": "portmap", # 通過iptables配置端口映射的二進制文件,配置端口映射
"capabilities": {
"portMappings": true
}
}
]
}
calico的CNI配置文件
# cat /etc/cni/net.d/10-calico.conflist
{
"name": "k8s-pod-network",
"cniVersion": "0.3.1",
"plugins": [
{
"type": "calico",
"log_level": "info",
"log_file_path": "/var/log/calico/cni/cni.log",
"datastore_type": "kubernetes",
"nodename": "kubernetes-master",
"mtu": 0,
"ipam": {
"type": "host-local",
"subnet": "usePodCidr"
},
"policy": {
"type": "k8s"
},
"kubernetes": {
"kubeconfig": "/etc/cni/net.d/calico-kubeconfig"
}
},
{
"type": "portmap",
"snat": true,
"capabilities": {"portMappings": true}
},
{
"type": "bandwidth",
"capabilities": {"bandwidth": true}
}
]
}
方案解讀
kubernetes提供了很多的網(wǎng)絡解決方案,相關的資料如下:
https://kubernetes.io/zh-cn/docs/concepts/cluster-administration/addons/
flannel方案
項目地址:https://github.com/coreos/flannel
Flannel是CoreOS 開發(fā)的項目,它是容器編排系統(tǒng)中最成熟的網(wǎng)絡方案之一,旨在實現(xiàn)更好的容器間和主機間網(wǎng)絡,由于其穩(wěn)定和配置簡單,所以它是CNI最早引入的一套方案。常見的 Kubernetes 集群部署工具和許多 Kubernetes 發(fā)行版都可以默認安裝 Flannel。
如果你需要一個穩(wěn)定而又簡單的網(wǎng)絡功能的話,不那么在乎安全性的話,F(xiàn)lannel是一個很好的選擇。
calico方案
項目地址:https://github.com/projectcalico/cni-plugin
Calico 是 Kubernetes 生態(tài)系統(tǒng)中另一種流行的網(wǎng)絡選擇。雖然 Flannel 被公認為是最簡單的選擇,但 Calico 以其性能、靈活性而聞名。Calico 的功能更為全面,除了通用的網(wǎng)絡連接,還涉及網(wǎng)絡安全和網(wǎng)絡策略管理,甚至Calico還可以在微服務的網(wǎng)絡治理中進行整合。Calico CNI 插件在 CNI 框架內(nèi)封裝了 Calico 的功能。
如果對你的環(huán)境而言,支持網(wǎng)絡策略是非常重要的一點,而且你對其他性能和功能也有需求,那么 Calico 會是一個理想的選擇。
canal方案
項目地址:https://github.com/projectcalico/canal
Canal 試圖將 Flannel 提供的網(wǎng)絡功能與 Calico 的網(wǎng)絡策略功能集成在一起,只不過在研發(fā)的時候,發(fā)現(xiàn)Flannel 和 Calico 這兩個項目的標準化和靈活性都想當標準,那集成就沒必要了,所以目前這個項目“爛尾”了。由于Canal的思路很好,業(yè)界習慣性地將 Flannel 和 Calico 的功能組合實施稱為“Canal”。
對于那些喜歡 Flannel 提供的網(wǎng)絡模型,同時喜歡 Calico 的網(wǎng)絡策略功能的人來說,Canal是一個選擇。
weave方案
項目地址:https://www.weave.works/oss/net/
Weave 是由 Weaveworks 提供的一種 Kubernetes CNI 網(wǎng)絡選項,它在集群中的每個節(jié)點上部署路由組件,從而實現(xiàn)主機之間創(chuàng)建更加靈活的網(wǎng)狀 overlay 網(wǎng)絡,借助于內(nèi)核級別的Open vSwitch 配置,從而實現(xiàn)具有一定程度的智能路由功能。除此之外,weave還具有想當?shù)木W(wǎng)絡策略功能,網(wǎng)絡加密傳輸功能等。
對于那些尋求功能豐富的網(wǎng)絡、同時希望不要增加大量復雜性或管理難度的人來說,Weave 是一個很好的選擇。
bandwidth - 帶寬、consumption - 消耗、encryption - 加密
資料來源:
https://docs.google.com/spreadsheets/d/12dQqSGI0ZcmuEy48nA0P_bPl7Yp17fNg7De47CYWzaM/edit#gid=404703955
小結
1.2.2 Calico環(huán)境
學習目標
這一節(jié),我們從 基礎知識、原理解讀、小結 三個方面來學習
基礎知識
簡介
Calico是一個開源的虛擬化網(wǎng)絡方案,用于為云原生應用實現(xiàn)互聯(lián)及策略控制.相較于 Flannel 來說,Calico 的優(yōu)勢是對網(wǎng)絡策略(network policy),它允許用戶動態(tài)定義 ACL 規(guī)則控制進出容器的數(shù)據(jù)報文,實現(xiàn)為 Pod 間的通信按需施加安全策略.不僅如此,Calico 還可以整合進大多數(shù)具備編排能力的環(huán)境,可以為 虛機和容器提供多主機間通信的功能。
Calico 本身是一個三層的虛擬網(wǎng)絡方案,它將每個節(jié)點都當作路由器,將每個節(jié)點的容器都當作是節(jié)點路由器的一個終端并為其分配一個 IP 地址,各節(jié)點路由器通過 BGP(Border Gateway Protocol)學習生成路由規(guī)則,從而將不同節(jié)點上的容器連接起來.因此,Calico 方案其實是一個純?nèi)龑拥慕鉀Q方案,通過每個節(jié)點協(xié)議棧的三層(網(wǎng)絡層)確保容器之間的連通性,這擺脫了 flannel host-gw 類型的所有節(jié)點必須位于同一二層網(wǎng)絡的限制,從而極大地擴展了網(wǎng)絡規(guī)模和網(wǎng)絡邊界。
官方地址:https://www.tigera.io/project-calico/
最新版本:v3.24.1 (20220827)、 v3.20.6 (20220802)、v3.21.6 (20220722)、 v3.23.3 (20220720)、v3.22.4 (20220720)
網(wǎng)絡模型
Calico為了實現(xiàn)更廣層次的虛擬網(wǎng)絡的應用場景,它支持多種網(wǎng)絡模型來滿足需求。
underlay network - BGP(三層虛擬網(wǎng)絡解決方案)
overlay network - IPIP(雙層IP實現(xiàn)跨網(wǎng)段效果)、VXLAN(數(shù)據(jù)包標識實現(xiàn)大二層上的跨網(wǎng)段通信)
設計思想
Calico不使用隧道或者NAT來實現(xiàn)轉發(fā),而是巧妙的把所有二三層流量轉換成三層流量,并通過host上路由配置完成跨host轉發(fā)。
為什么用calico
原理解讀
calico
Calico是一個開源的虛擬化網(wǎng)絡方案,用于為云原生應用實現(xiàn)互聯(lián)及策略控制.相較于 Flannel 來說,Calico 的優(yōu)勢是對網(wǎng)絡策略(network policy),它允許用戶動態(tài)定義 ACL 規(guī)則控制進出容器的數(shù)據(jù)報文,實現(xiàn)為 Pod 間的通信按需施加安全策略.不僅如此,Calico 還可以整合進大多數(shù)具備編排能力的環(huán)境,可以為 虛機和容器提供多主機間通信的功能。
我們平常使用Calico主要用到的是它的網(wǎng)絡策略功能
軟件結構
Felix
每個節(jié)點都有,負責配置路由、ACL、向etcd宣告狀態(tài)等
BIRD
每個節(jié)點都有,負責把 Felix 寫入Kernel的路由信息 分發(fā)到整個 Calico網(wǎng)絡,確保 workload 連通
etcd
存儲calico自己的狀態(tài)數(shù)據(jù),可以結合kube-apiserver來工作
官方推薦;
< 50節(jié)點,可以結合 kube-apiserver 來實現(xiàn)數(shù)據(jù)的存儲
> 50節(jié)點,推薦使用獨立的ETCD集群來進行處理。
參考資料:
https://projectcalico.docs.tigera.io/getting-started/kubernetes/self-managed-onprem/onpremises#install-calico
Route Reflector
路由反射器,用于集中式的動態(tài)生成所有主機的路由表,非必須選項
超過100個節(jié)點推薦使用:
https://projectcalico.docs.tigera.io/getting-started/kubernetes/rancher#concepts
Calico編排系統(tǒng)插件
實現(xiàn)更廣范圍的虛擬網(wǎng)絡解決方案。
參考資料:https://docs.projectcalico.org/reference/architecture/overview
工作模式
對于節(jié)點量少的情況下,我們推薦使用左側默認的模式,當節(jié)點量多的時候,我們推薦使用右側的反射器模式
小結
1.2.3 Calico部署
學習目標
這一節(jié),我們從 環(huán)境解析、簡單實踐、小結 三個方面來學習
環(huán)境解析
k8s環(huán)境上的calico邏輯
confd
- 統(tǒng)一管控 Calico 數(shù)據(jù)存儲以及 BGP 配置的輕量級的配置管理工具。
- 當配置文件發(fā)生變化時,動態(tài)更新和生成BIRD 配置文件
Dikastes
- 為 Istio 服務網(wǎng)格實施網(wǎng)絡策略。作為 Istio Envoy 的 sidecar 代理在集群上運行。
CNI plugin
- 為 Kubernetes 集群提供 Calico 網(wǎng)絡,必須安裝在 Kubernetes 集群中的每個節(jié)點上。
Datastore plugin
- 獨立使用etcd作為Calico的數(shù)據(jù)存儲平臺,特點在于獨立擴展數(shù)據(jù)存儲
- 結合K8s的apiserver實現(xiàn)數(shù)據(jù)存儲到etcd中,特點在于使用 Kubernetes的存儲、RBAC、審計功能為Calico服務
IPAM plugin
- 使用 Calico 的 IP 池資源來控制 IP 地址如何分配給集群內(nèi)的 Pod。
kube-controllers
- 監(jiān)控 Kubernetes API 并根據(jù)集群狀態(tài)執(zhí)行操作
- 主要是策略、命名空間、服務賬號、負載、節(jié)點等通信策略的控制
Typha
- 通過減少每個節(jié)點對數(shù)據(jù)存儲的影響來增加規(guī)模。在數(shù)據(jù)存儲和 Felix 實例之間作為守護進程運行。
參考資料:
https://projectcalico.docs.tigera.io/reference/architecture/overview
基礎環(huán)境支持
linux 主機基本要求:
x86-64、arm64、ppc64le 或 s390x 處理器
2CPU
2GB 內(nèi)存
10GB 可用磁盤空間
RedHat Enterprise Linux 7.x+、CentOS 7.x+、Ubuntu 16.04+ 或 Debian 9.x+
確保 Calico 可以在主機上進行管理cali和接口
其他需求:
kubernetes集群配置了 --pod-network-cidr 屬性
參考資料:
https://projectcalico.docs.tigera.io/getting-started/kubernetes/quickstart
部署解析
對于calico在k8s集群上的部署來說,為了完成上面四個組件的部署,這里會涉及到兩個部署組件
組件名 | 組件作用 |
---|---|
calico-node | 需要部署到所有集群節(jié)點上的代理守護進程,提供封裝好的Felix和BIRD |
calico-kube-controller | 專用于k8s上對calico所有節(jié)點管理的中央控制器。負責calico與k8s集群的協(xié)同及calico核心功能實現(xiàn)。 |
部署步驟
1 獲取資源配置文件
從calico官網(wǎng)獲取相關的配置信息
2 定制CIDR配置
定制calico自身對于pod網(wǎng)段的配置信息,并且清理無關的網(wǎng)絡其他插件
3 定制pod的manifest文件分配網(wǎng)絡配置
默認的k8s集群在啟動的時候,會有一個cidr的配置,有可能與calico進行沖突,那么我們需要修改一下
4 應用資源配置文件
注意事項:
對于calico來說,它自己會生成自己的路由表,如果路由表中存在響應的記錄,默認情況下會直接使用,而不是覆蓋掉當前主機的路由表
所以如果我們在部署calico之前,曾經(jīng)使用過flannel,尤其是flannel的host-gw模式的話,一定要注意,在使用calico之前,將之前所有的路由表信息清空,否則無法看到calico的tunl的封裝效果
簡單實踐
環(huán)境部署
1 獲取資源清單文件
mkdir /data/kubernetes/network/calico -p
cd /data/kubernetes/network/calico/
curl https://docs.projectcalico.org/manifests/calico.yaml -O
cp calico.yaml{,.bak}
2 配置資源清單文件
# vim calico.yaml
---- 官網(wǎng)推薦的修改內(nèi)容
4546 - name: CALICO_IPV4POOL_CIDR
4547 value: "10.244.0.0/16"
---- 方便我們的后續(xù)實驗,新增調小子網(wǎng)段的分配
4548 - name: CALICO_IPV4POOL_BLOCK_SIZE
4549 value: "24"
配置解析:
開放默認注釋的CALICO_IPV4POOL_CIDR變量,然后定制我們當前的pod的網(wǎng)段范圍即可
原則上來說,我們修改官方提示的屬性即可
3 定制pod的manifest文件分配網(wǎng)絡配置
# vim calico.yaml
---- 修改下面的內(nèi)容
64 "ipam": {
65 "type": "calico-ipam"
66 },
---- 修改后的內(nèi)容
64 "ipam": {
65 "type": "host-local",
66 "subnet": "usePodCidr"
67 },
---- 定制calico使用k8s集群節(jié)點的地址
4551 - name: USE_POD_CIDR
4552 value: "true"
配置解析:
Calico默認并不會從Node.Spec.PodCIDR中分配地址,但可通過USE_POD_CIDR變量并結合host-local這一IPAM插件以強制從PodCIDR中分配地址
4 定制默認的docker鏡像
查看默認的鏡像
# grep docker.io calico.yaml | uniq
image: docker.io/calico/cni:v3.24.1
image: docker.io/calico/node:v3.24.1
image: docker.io/calico/kube-controllers:v3.24.1
獲取鏡像
for i in $(grep docker.io calico.yaml | uniq | awk -F'/' '{print $NF}')
do
docker pull calico/$i
docker tag calico/$i kubernetes-register.superopsmsb.com/google_containers/$i
docker push kubernetes-register.superopsmsb.com/google_containers/$i
docker rmi calico/$i
done
修改為定制的鏡像
sed -i 's#docker.io/calico#kubernetes-register.superopsmsb.com/google_containers#g' calico.yaml
查看效果
# grep google calico.yaml
image: kubernetes-register.superopsmsb.com/google_containers/cni:v3.24.1
image: kubernetes-register.superopsmsb.com/google_containers/cni:v3.24.1
image: kubernetes-register.superopsmsb.com/google_containers/node:v3.24.1
image: kubernetes-register.superopsmsb.com/google_containers/node:v3.24.1
image: kubernetes-register.superopsmsb.com/google_containers/kube-controllers:v3.24.1
5 應用資源配置文件
清理之前的flannel插件
kubectl delete -f kube-flannel.yml
kubectl get pod -n kube-system | grep flannel
這個時候,先清除舊網(wǎng)卡,然后最好重啟一下主機,直接清空所有的路由表信息
ifconfig flannel.1
reboot
重啟后,查看網(wǎng)絡效果
注意:
為了避免后續(xù)calico網(wǎng)絡測試的異常,我們這里最好只留下一個網(wǎng)卡 eth0
應用calico插件
kubectl apply -f calico.yaml
在calico-node部署的時候,會啟動多個進程
# kubectl get pod -n kube-system | egrep 'NAME|calico'
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-549f7748b5-xqz8j 0/1 ContainerCreating 0 9s
calico-node-74c5w 0/1 Init:0/3 0 9s
...
環(huán)境部署完畢后,查看效果
# kubectl get pod -n kube-system | egrep 'NAME|calico'
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-549f7748b5-xqz8j 0/1 Running 0 39s
calico-node-74c5w 0/1 Running 0 39s
...
每個calico節(jié)點上都有多個進程,分別來處理不同的功能
]# ps aux | egrep 'NAME | calico'
root 9315 0.5 1.1 1524284 43360 ? Sl 15:29 0:00 calico-node -confd
root 9316 0.2 0.8 1155624 32924 ? Sl 15:29 0:00 calico-node -monitor-token
root 9317 2.8 1.0 1598528 40992 ? Sl 15:29 0:02 calico-node -felix
root 9318 0.3 0.9 1155624 35236 ? Sl 15:29 0:00 calico-node -monitor-addresses
root 9319 0.3 0.8 1155624 33460 ? Sl 15:29 0:00 calico-node -status-reporter
root 9320 0.2 0.7 1155624 30364 ? Sl 15:29 0:00 calico-node -allocate-tunnel-addrs
測試效果
獲取鏡像
docker pull nginx
docket tag nginx kubernetes-register.superopsmsb.com/superopsmsb/nginx:1.23.1
docker push kubernetes-register.superopsmsb.com/superopsmsb/nginx:1.23.1
docker rmi nginx
創(chuàng)建一個deployment
kubectl create deployment pod-deployment --image=kubernetes-register.superopsmsb.com/superopsmsb/nginx:1.23.1 --replicas=3
查看pod
# kubectl get pod
NAME READY STATUS RESTARTS AGE
pod-deployment-554dff674-267gq 1/1 Running 0 48s
pod-deployment-554dff674-c8cjs 1/1 Running 0 48s
pod-deployment-554dff674-pxrwb 1/1 Running 0 48s
暴露一個service
kubectl expose deployment pod-deployment --port=80 --target-port=80
確認效果
kubectl get service
curl 10.108.138.97
小結
1.2.4 簡單實踐
學習目標
這一節(jié),我們從 網(wǎng)絡解析、命令完善、小結 三個方面來學習
網(wǎng)絡解析
calico部署完畢后,會生成一系列的自定義配置屬性信息
自動生成一個api版本信息
# kubectl api-versions | grep crd
crd.projectcalico.org/v1
該api版本信息中有大量的配置屬性
kubectl api-resources | grep crd.pro
這里面的 ippools 里面包含了calico相關的網(wǎng)絡屬性信息
# kubectl get ippools
NAME AGE
default-ipv4-ippool 37m
查看這里配置的calico相關的信息
# kubectl get ippools default-ipv4-ippool -o yaml
apiVersion: crd.projectcalico.org/v1
kind: IPPool
...
spec:
allowedUses:
- Workload
- Tunnel
blockSize: 24
cidr: 10.244.0.0/16
ipipMode: Always
natOutgoing: true
nodeSelector: all()
vxlanMode: Never
結果顯式:
這里的calico采用的模型就是 ipip模型,分配的網(wǎng)段是使我們定制的 cidr網(wǎng)段,而且子網(wǎng)段也是我們定制的 24位掩碼
環(huán)境創(chuàng)建完畢后,會生成一個tunl0的網(wǎng)卡,所有的流量會走這個tunl0網(wǎng)卡
確認網(wǎng)卡和路由信息
]# ifconfig | grep flags
]# ip route list | grep tun
10.244.1.0/24 via 10.0.0.13 dev tunl0 proto bird onlink
10.244.2.0/24 via 10.0.0.14 dev tunl0 proto bird onlink
10.244.3.0/24 via 10.0.0.15 dev tunl0 proto bird onlink
10.244.4.0/24 via 10.0.0.16 dev tunl0 proto bird onlink
10.244.5.0/24 via 10.0.0.17 dev tunl0 proto bird onlink
結果顯示:
calico模型中,默認使用的是tunl0虛擬網(wǎng)卡實現(xiàn)數(shù)據(jù)包的專線轉發(fā)
測試效果
由于在calico的默認網(wǎng)絡模型是 IPIP,所以我們在進行數(shù)據(jù)包測試的時候,可以通過直接抓取宿主機數(shù)據(jù)包,來發(fā)現(xiàn)雙層ip效果
kubectl get pod -o wide
在master1上采用ping的方式來測試 node2上的節(jié)點pod
[root@kubernetes-master1 /data/kubernetes/network/calico]# ping -c 1 10.244.4.3
PING 10.244.4.3 (10.244.4.3) 56(84) bytes of data.
64 bytes from 10.244.4.3: icmp_seq=1 ttl=63 time=0.794 ms
在node2上檢測數(shù)據(jù)包的效果
[root@kubernetes-node2 ~]# tcpdump -i eth0 -nn ip host 10.0.0.16 and host 10.0.0.12
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
15:38:52.231680 IP 10.0.0.12 > 10.0.0.16: IP 10.244.0.1 > 10.244.4.3: ICMP echo request, id 19189, seq 1, length 64 (ipip-proto-4)
15:38:52.231989 IP 10.0.0.16 > 10.0.0.12: IP 10.244.4.3 > 10.244.0.1: ICMP echo reply, id 19189, seq 1, length 64 (ipip-proto-4)
15:38:54.666538 IP 10.0.0.16.33992 > 10.0.0.12.179: Flags [P.], seq 4281052787:4281052806, ack 3643645463, win 58, length 19: BGP
15:38:54.666962 IP 10.0.0.12.179 > 10.0.0.16.33992: Flags [.], ack 19, win 58, length 0
結果顯式:
每個數(shù)據(jù)包都是基于雙層ip嵌套的方式來進行傳輸,而且協(xié)議是 ipip-proto-4
結合路由的分發(fā)詳情,可以看到具體的操作效果。
具體效果:10.244.0.1 -> 10.0.0.12 -> 10.0.0.16 -> 10.244.6.3
命令完善
簡介
calico本身是一個復雜的系統(tǒng),復雜到它自己提供一個非常重要的Restful接口,結合calicoctl命令來管理自身的相關屬性信息,calicoctl可以直接與etcd進行操作,也可以通過kube-apiserver的方式與etcd來進行操作。默認情況下,它與kube-apiserver通信的認證方式與kubectl的命令使用同一個context。但是我們還是推薦,使用手工定制的一個配置文件。
calicoctl 是運行在集群之外的,用于管理集群功能的一個重要的組件。calicoctl 的安裝方式很多,常見的方式有:單主機方式、kubectl命令插件方式、pod方式、主機容器方式。我們需要自己選擇一種適合自己的方式
參考資料:https://projectcalico.docs.tigera.io/getting-started/kubernetes/hardway/the-calico-datastore#install
獲取專用命令
cd /usr/local/bin/
curl -L https://github.com/projectcalico/calico/releases/download/v3.24.1/calicoctl-linux-amd64 -o calicoctl
chmod +x calicoctl
查看幫助
# calicoctl --help
Usage:
calicoctl [options] <command> [<args>...]
命令的基本演示
查看ip的管理
calicoctl ipam --help
查看ip的信息
# calicoctl ipam show
+----------+---------------+-----------+------------+--------------+
| GROUPING | CIDR | IPS TOTAL | IPS IN USE | IPS FREE |
+----------+---------------+-----------+------------+--------------+
| IP Pool | 10.244.0.0/16 | 65536 | 0 (0%) | 65536 (100%) |
+----------+---------------+-----------+------------+--------------+
查看信息的顯式效果
calicoctl ipam show --help
顯式相關的配置屬性
# calicoctl ipam show --show-configuration
+--------------------+-------+
| PROPERTY | VALUE |
+--------------------+-------+
| StrictAffinity | false |
| AutoAllocateBlocks | true |
| MaxBlocksPerHost | 0 |
+--------------------+-------+
將calico整合到kubectl里面
定制kubectl 插件子命令
# cd /usr/local/bin/
# cp -p calicoctl kubectl-calico
測試效果
# kubectl calico --help
Usage:
kubectl-calico [options] <command> [<args>...]
后續(xù)的操作基本上都一樣了,比如獲取網(wǎng)絡節(jié)點效果
[root@kubernetes-master1 /usr/local/bin]# kubectl calico node status
Calico process is running.
IPv4 BGP status
+--------------+-------------------+-------+----------+-------------+
| PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO |
+--------------+-------------------+-------+----------+-------------+
| 10.0.0.15 | node-to-node mesh | up | 07:30:48 | Established |
| 10.0.0.17 | node-to-node mesh | up | 07:30:48 | Established |
| 10.0.0.13 | node-to-node mesh | up | 07:30:48 | Established |
| 10.0.0.14 | node-to-node mesh | up | 07:30:51 | Established |
| 10.0.0.16 | node-to-node mesh | up | 07:31:41 | Established |
+--------------+-------------------+-------+----------+-------------+
IPv6 BGP status
No IPv6 peers found.
注意:
這里查看的是除了自己網(wǎng)段之外的其他節(jié)點的路由信息
小結
1.2.5 BGP實踐
學習目標
這一節(jié),我們從 bgp改造、反射器實踐、小結 三個方面來學習
bgp改造
簡介
對于現(xiàn)有的calico環(huán)境,我們?nèi)绻枰褂肂GP環(huán)境,我們可以直接使用一個配置清單來進行修改calico環(huán)境即可。我們這里先來演示一下如何使用calicoctl修改配置屬性。
獲取當前的配置屬性
# kubectl calico get ipPools
NAME CIDR SELECTOR
default-ipv4-ippool 10.244.0.0/16 all()
# kubectl calico get ipPools default-ipv4-ippool -o yaml
apiVersion: projectcalico.org/v3
kind: IPPool
...
spec:
blockSize: 24
cidr: 10.244.0.0/16
ipipMode: Always
natOutgoing: true
nodeSelector: all()
vxlanMode: Never
定制資源配置文件
kubectl calico get ipPools default-ipv4-ippool -o yaml > default-ipv4-ippool.yaml
修改配置文件
# cat default-ipv4-ippool.yaml
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
name: default-ipv4-ippool
spec:
blockSize: 24
cidr: 10.244.0.0/16
ipipMode: CrossSubnet
natOutgoing: true
nodeSelector: all()
vxlanMode: Never
配置解析:
僅僅將原來的Always 更換成 CrossSubnet(跨節(jié)點子網(wǎng)) 模式即可
vxlanMode 的兩個值可以實現(xiàn)所謂的 BGP with vxlan的效果
應用資源配置文件
# kubectl calico apply -f default-ipv4-ippool.yaml
Successfully applied 1 'IPPool' resource(s)
檢查效果
查看路由信息
[root@kubernetes-master1 ~]# ip route list | grep via
default via 10.0.0.2 dev eth0
10.244.1.0/24 via 10.0.0.13 dev eth0 proto bird
10.244.2.0/24 via 10.0.0.14 dev eth0 proto bird
10.244.3.0/24 via 10.0.0.15 dev eth0 proto bird
10.244.4.0/24 via 10.0.0.16 dev eth0 proto bird
10.244.5.0/24 via 10.0.0.17 dev eth0 proto bird
結果顯式:
更新完畢配置后,動態(tài)路由的信息就發(fā)生改變了,不再完全是 tunl0 網(wǎng)卡了,而是變成了通過具體的物理網(wǎng)卡eth0 轉發(fā)出去了
在master1上ping在節(jié)點node2上的pod
[root@kubernetes-master1 ~]# ping -c 1 10.244.4.3
PING 10.244.4.3 (10.244.4.3) 56(84) bytes of data.
64 bytes from 10.244.4.3: icmp_seq=1 ttl=63 time=0.671 ms
由于這次是直接通過節(jié)點進行轉發(fā)的,所以我們在node2節(jié)點上抓包的時候,直接通過內(nèi)層ip抓取即可。
[root@kubernetes-node2 ~]# tcpdump -i eth0 -nn ip host 10.244.4.3
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
15:47:32.906462 IP 10.0.0.12 > 10.244.4.3: ICMP echo request, id 28248, seq 1, length 64
15:47:32.906689 IP 10.244.4.3 > 10.0.0.12: ICMP echo reply, id 28248, seq 1, length 64
結果顯示:
他們實現(xiàn)了直接的連通,無需進行數(shù)據(jù)包的轉換了,效率更高一點
反射器實踐
當前節(jié)點的網(wǎng)絡效果
查看當前節(jié)點的網(wǎng)絡效果
[root@kubernetes-master1 ~]# kubectl calico node status
Calico process is running.
IPv4 BGP status
+--------------+-------------------+-------+----------+-------------+
| PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO |
+--------------+-------------------+-------+----------+-------------+
| 10.0.0.15 | node-to-node mesh | up | 07:30:48 | Established |
| 10.0.0.17 | node-to-node mesh | up | 07:30:48 | Established |
| 10.0.0.13 | node-to-node mesh | up | 07:30:48 | Established |
| 10.0.0.14 | node-to-node mesh | up | 07:30:51 | Established |
| 10.0.0.16 | node-to-node mesh | up | 07:31:41 | Established |
+--------------+-------------------+-------+----------+-------------+
需求
當前的calico節(jié)點的網(wǎng)絡狀態(tài)是 BGP peer 的模型效果,也就是說 每個節(jié)點上都要維護 n-1 個路由配置信息,整個集群中需要維護 n*(n-1) 個路由效果,這在節(jié)點量非常多的場景中,不是我們想要的。
所以我們需要實現(xiàn)一種 BGP reflecter 的效果。
如果我們要做 BGP reflecter 效果的話,需要對反射器角色做冗余,如果我們的集群是一個多主集群的話,可以將集群的master節(jié)點作為bgp的reflecter角色,從而實現(xiàn)反射器的冗余。
1 定制反射器角色
2 后端節(jié)點使用反射器
3 關閉默認的網(wǎng)格效果
1 創(chuàng)建反射器角色
定制資源定義文件 01-calico-reflector-master.yaml
apiVersion: projectcalico.org/v3
kind: Node
metadata:
labels:
route-reflector: true
name: kubernetes-master1
spec:
bgp:
ipv4Address: 10.0.0.12/16
ipv4IPIPTunnelAddr: 10.244.0.1
routeReflectorClusterID: 1.1.1.1
屬性解析;
metadata.labels 是非常重要的,因為它需要被后面的節(jié)點來進行獲取
metadata.name 的屬性,必須是通過 calicoctl get nodes 獲取到的節(jié)點名稱。
spec.bgp.ipv4Address必須是 指定節(jié)點的ip地址
spec.bgp.ipv4IPIPTunnelAddr必須是 指定節(jié)點上tunl0的地址
spec.bgp.routeReflectorClusterID 是BGP網(wǎng)絡中的唯一標識,所以這里的集群標識只要唯一就可以了
應用資源配置文件
kubectl calico apply -f 01-calico-reflector-master.yaml
2 更改節(jié)點的網(wǎng)絡模型為 reflecter模型
定制資源定義文件 02-calico-reflector-bgppeer.yaml
kind: BGPPeer
apiVersion: projectcalico.org/v3
metadata:
name: bgppeer-demo
spec:
nodeSelector: all()
peerSelector: route-reflector=="true"
屬性解析;
spec.nodeSelector 指定的所有后端節(jié)點
spec.peerSelector 指定的是反射器的標簽,標識所有的后端節(jié)點與這個反射器進行數(shù)據(jù)交流
應用資源配置文件
kubectl calico apply -f 02-calico-reflector-bgppeer.yaml
3 關閉默認的網(wǎng)格效果
定制資源定義文件 03-calico-reflector-defaultconfig.yaml
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
name: default
spec:
logSeverityScreen: Info
nodeToNodeMeshEnabled: false
asNumber: 63400
屬性解析;
metadata.name 在這里最好是default,因為我們要對BGP默認的網(wǎng)絡效果進行關閉
spec.nodeToNodeMeshEnabled 關閉后端節(jié)點的BGP peer默認狀態(tài) -- 即點對點通信關閉
spec.asNumber 指定的是后端節(jié)點間使用反射器的時候,我們要在一個標志號內(nèi),這里隨意寫一個
應用資源配置文件
kubectl calico apply -f 03-calico-reflector-defaultconfig.yaml
查看效果
[root@kubernetes-master1 ~/txt]# kubectl calico node status
...
IPv4 BGP status
+--------------+---------------+-------+----------+-------------+
| PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO |
+--------------+---------------+-------+----------+-------------+
| 10.0.0.13 | node specific | up | 07:51:47 | Established |
| 10.0.0.14 | node specific | up | 07:51:49 | Established |
| 10.0.0.15 | node specific | up | 07:51:49 | Established |
| 10.0.0.16 | node specific | up | 07:51:47 | Established |
| 10.0.0.17 | node specific | up | 07:51:47 | Established |
+--------------+---------------+-------+----------+-------------+
結果顯式:
默認的點對點通信方式就已經(jīng)丟失了,剩下了反射器模式
小結
1.2.6 策略實踐
學習目標
這一節(jié),我們從 屬性解讀、基本控制、小結 三個方面來學習。
屬性解讀
策略簡介
為了使用Network Policy,Kubernetes引入了一個新的資源對象Network Policy,供用戶設置Pod間網(wǎng)絡訪問的策略。策略控制器用于監(jiān)控指定區(qū)域創(chuàng)建對象(pod)時所生成的新API端點,并按需為其附加網(wǎng)絡策略。
對于Pod對象來說,網(wǎng)絡流量分為 流入(Ingress)和流出(Egress)兩個方向,每個方向包含允許和禁止兩種控制策略,默認情況下,所有的策略都是允許的,應用策略后,所有未經(jīng)明確允許的流量都將拒絕。
注意:
網(wǎng)絡策略的控制,可以是多個級別:
集群級別、namespace級別、Pod級別、ip級別、端口級別
資源對象屬性
apiVersion: networking.k8s.io/v1 # 資源隸屬的API群組及版本號
kind: NetworkPolicy # 資源類型的名稱,名稱空間級別的資源;
metadata: # 資源元數(shù)據(jù)
name <string> # 資源名稱標識
namespace <string> # NetworkPolicy是名稱空間級別的資源
spec: # 期望的狀態(tài)
podSelector <Object> # 當前規(guī)則生效的一組目標Pod對象,必選字段;空值表示當前名稱空間中的所有Pod資源
policyTypes <[]string> # Ingress表示生效ingress字段;Egress表示生效egress字段,同時提供表示二者均有效
ingress <[]Object> # 入站流量源端點對象列表,白名單,空值表示“所有”
- from <[]Object> # 具體的端點對象列表,空值表示所有合法端點
- ipBlock <Object> # IP地址塊范圍內(nèi)的端點,不能與另外兩個字段同時使用
- namespaceSelector <Object> # 匹配的名稱空間內(nèi)的端點
podSelector <Object> # 由Pod標簽選擇器匹配到的端點,空值表示<none>
ports <[]Object> # 具體的端口對象列表,空值表示所有合法端口
egress <[]Object> # 出站流量目標端點對象列表,白名單,空值表示“所有”
- to <[]Object> # 具體的端點對象列表,空值表示所有合法端點,格式同ingres.from;
ports <[]Object> # 具體的端口對象列表,空值表示所有合法端口
注意:
入棧和出棧哪個策略生效,由 policyTypes 來決定。
如果僅配置了podSelector,表明,當前限制僅限于當前的命名空間
配置示例
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
- Egress
ingress:
- from:
- ipBlock:
cidr: 10.244.0.0/16
except:
- 10.244.1.0/24
- namespacesSelector:
matchLabels:
project: develop
- podSelector:
matchLabels:
arch: frontend
ports:
- protocol: TCP
port: 6379
egress:
- to:
- ipBlock:
cidr: 10.244.0.0/24
ports:
- protocol: TCP
port: 3306
準備工作
在default命名空間創(chuàng)建應用
[root@kubernetes-master1 ~]# kubectl create deployment nginx-web --image=kubernetes-register.superopsmsb.com/superopsmsb/nginx_web:v0.1
[root@kubernetes-master1 ~]# kubectl expose deployment nginx-web --port=80
在superopsmsb命名空間創(chuàng)建應用
[root@kubernetes-master1 ~]# kubectl create deployment nginx-web --image=kubernetes-register.superopsmsb.com/superopsmsb/nginx_web:v0.1 --namespace=superopsmsb
[root@kubernetes-master1 ~]# kubectl expose deployment nginx-web --port=80 --namespace=superopsmsb
確認效果
[root@kubernetes-master1 ~]# kubectl get pod -o wide
NAME READY... AGE IP ...
nginx-web-5865bb968d-759lc 1/1 ... 10s 10.244.1.4 ...
[root@kubernetes-master1 ~]# kubectl get pod -o wide -n superopsmsb
NAME READY... AGE IP ...
nginx-web-65d688fd6-h6sbpp 1/1 ... 10s 10.244.1.5 ...
開啟superopsmsb的測試容器
[root@kubernetes-master1 ~]# kubectl exec -it nginx-web-65d688fd6-h6sbp -n superopsmsb -- /bin/bash
root@nginx-web-65d688fd6-h6sbp:/# apt update; apt install net-tools iputils-ping dnsutils curl -y
進入到容器里面查看效果
[root@kubernetes-master1 ~]# kubectl exec -it nginx-web-5865bb968d-759lc -- /bin/bash
root@nginx-web-5865bb968d-759lc:/# apt update; apt install net-tools iputils-ping dnsutils curl -y
域名檢測
root@nginx-web-5865bb968d-759lc:/# nslookup nginx-web
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: nginx-web.default.svc.cluster.local
Address: 10.101.181.105
root@nginx-web-5865bb968d-759lc:/# nslookup nginx-web.superopsmsb.svc.cluster.local
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: nginx-web.superopsmsb.svc.cluster.local
Address: 10.105.110.175
ping檢測
root@nginx-web-5865bb968d-759lc:/# ifconfig | grep 244
inet 10.244.1.4 netmask 255.255.255.255 broadcast 0.0.0.0
RX packets 22442 bytes 20956160 (19.9 MiB)
root@nginx-web-5865bb968d-759lc:/# ping -c 1 10.244.1.5
PING 10.244.1.5 (10.244.1.5) 56(84) bytes of data.
64 bytes from 10.244.1.5: icmp_seq=1 ttl=63 time=0.357 ms
基本控制
默認拒絕規(guī)則
查看資源清單文件
# cat 01_kubernetes_secure_networkpolicy_refuse.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
namespace: superopsmsb
spec:
podSelector: {}
policyTypes: ["Ingress", "Egress"]
應用資源清單文件
# kubectl apply -f 01_kubernetes_secure_networkpolicy_refuse.yaml
networkpolicy.networking.k8s.io/deny-all-ingress created
嘗試default空間資源訪問superopsmsb空間資源
root@nginx-web-5865bb968d-759lc:/# ping -c 1 10.244.1.5
PING 10.244.1.5 (10.244.1.5) 56(84) bytes of data.
--- 10.244.1.5 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms
root@nginx-web-5865bb968d-759lc:/# curl nginx-web.superopsmsb.svc.cluster.local
curl: (28) Failed to connect to nginx-web.superopsmsb.svc.cluster.local port 80: Connection timed out
結果顯示:
訪問失敗
default空間資源訪問非superopsmsb空間資源正常。
root@nginx-web-5865bb968d-759lc:/# curl nginx-web
Hello Nginx, nginx-web-5865bb968d-759lc-1.23.0
默認啟用規(guī)則
查看資源清單文件
# cat 02_kubernetes_secure_networkpolicy_allow.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-ingress
namespace: superopsmsb
spec:
podSelector: {}
policyTypes: ["Ingress", "Egress"]
egress:
- {}
ingress:
- {}
應用資源清單文件
# kubectl apply -f 02_kubernetes_secure_networkpolicy_allow.yaml
networkpolicy.networking.k8s.io/allow-all-ingress created
在default空間訪問superopsmsb空間資源
root@nginx-web-5865bb968d-759lc:/# curl nginx-web.superopsmsb.svc.cluster.local
Hello Nginx, nginx-web-65d688fd6-h6sbp-1.23.0
root@nginx-web-5865bb968d-759lc:/# ping -c 1 10.244.1.5
PING 10.244.1.5 (10.244.1.5) 56(84) bytes of data.
64 bytes from 10.244.1.5: icmp_seq=1 ttl=63 time=0.181 ms
結果顯示:
網(wǎng)絡策略成功了,而且多個網(wǎng)絡策略可以疊加
注意:僅僅同名策略或者同類型策略可以覆蓋
清理網(wǎng)絡策略
# kubectl delete -f 02_kubernetes_secure_networkpolicy_allow.yaml
當前namespace的流量限制
查看資源清單文件
# cat 03_kubernetes_secure_networkpolicy_ns.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-current-ns
namespace: superopsmsb
spec:
podSelector: {}
policyTypes: ["Ingress", "Egress"]
egress:
- to:
- podSelector: {}
ingress:
- from:
- podSelector: {}
配置解析:
雖然設置了egress和ingress屬性,但是下面的podSelector沒有選擇節(jié)點,表示只有當前命名空間所有節(jié)點不受限制
應用資源清單文件
# kubectl apply -f 03_kubernetes_secure_networkpolicy_ns.yaml
networkpolicy.networking.k8s.io/allow-current-ns created
default資源訪問superopsmsb資源
root@nginx-web-5865bb968d-759lc:/# curl nginx-web.superopsmsb.svc.cluster.local
curl: (28) Failed to connect to nginx-web.superopsmsb.svc.cluster.local port 80: Connection timed out
root@nginx-web-5865bb968d-759lc:/# ping -c 1 10.244.1.5
PING 10.244.1.5 (10.244.1.5) 56(84) bytes of data.
結果顯示:
訪問失敗
superopsmsb資源訪問同命名空間的其他資源
root@nginx-web-65d688fd6-h6sbp:/# ping 10.244.1.2
PING 10.244.1.2 (10.244.1.2) 56(84) bytes of data.
64 bytes from 10.244.1.2: icmp_seq=1 ttl=63 time=0.206 ms
結果顯示:
同命名空間可以正常訪問
小結
1.2.7 流量管控
學習目標
這一節(jié),我們從 ip限制實踐、pod限制實踐、小結 三個方面來學習。
ip限制知識
準備工作
準備同名空間的兩個測試pod
終端1
kubectl run superopsmsb-client1 --image=kubernetes-register.superopsmsb.com/superopsmsb/busybox -n superopsmsb --rm -it -- /bin/sh
終端2
kubectl run superopsmsb-client2 --image=kubernetes-register.superopsmsb.com/superopsmsb/busybox -n superopsmsb --rm -it -- /bin/sh
簡介
查看資源清單文件
# cat 04_kubernetes_secure_networkpolicy_ns_pod.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-ns-pod
namespace: superopsmsb
spec:
podSelector: {}
policyTypes: ["Ingress", "Egress"]
egress:
- to:
- podSelector: {}
ingress:
- from:
- ipBlock:
cidr: 10.244.0.0/16
except:
- 10.244.2.0/24
ports:
- protocol: TCP
port: 80
配置解析:
雖然設置了egress和ingress屬性,但是下面的podSelector沒有選擇節(jié)點,表示只有當前命名空間所有節(jié)點不受限制
應用資源對象文件
# kubectl apply -f 04_kubernetes_secure_networkpolicy_ns_pod.yaml
networkpolicy.networking.k8s.io/deny-ns-pod created
3網(wǎng)段測試容器查看效果
/ # ifconfig | grep 244
inet addr:10.244.3.7 Bcast:0.0.0.0 Mask:255.255.255.255
/ # wget 10.244.1.5
Connecting to 10.244.1.5 (10.244.1.5:80)
index.html 100% |*****************************************************| 46 0:00:00 ETA
/
2網(wǎng)段測試容器查看效果
/ # ifconfig | grep 244
inet addr:10.244.2.6 Bcast:0.0.0.0 Mask:255.255.255.255
/ # wget 10.244.1.5
Connecting to 10.244.1.5 (10.244.1.5:80)
wget: can't connect to remote host (10.244.1.5): Connection timed out
/
結果顯示:
同namespace可以進行ip級別的訪問測試
pod限制實踐
實踐
查看在ip限制的基礎上,擴充pod限制資源清單文件
# cat 05_kubernetes_secure_networkpolicy_ns_port.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: egress-controller
namespace: superopsmsb
spec:
podSelector: {}
policyTypes: ["Egress"]
egress:
- to:
ports:
- protocol: UDP
port: 53
- to:
ports:
- protocol: TCP
port: 80
配置解析:
雖然設置了egress和ingress屬性,但是下面的podSelector沒有選擇節(jié)點,表示只有當前命名空間所有節(jié)點不受限制
應用資源對象文件
# kubectl apply -f 05_kubernetes_secure_networkpolicy_ns_port.yaml
networkpolicy.networking.k8s.io/egress-controller created
在所有pod測試容器中
/ # nslookup nginx-web.default.svc.cluster.local
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: nginx-web.default.svc.cluster.local
Address 1: 10.101.181.105 nginx-web.default.svc.cluster.local
/ # nslookup nginx-web
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: nginx-web
Address 1: 10.105.110.175 nginx-web.superopsmsb.svc.cluster.local
結果顯示:
在不影響之前的策略的前提下,擴充了dns的解析功能
小結
1.2.8 基準測試
學習目標
這一節(jié),我們從 軟件簡介、簡單實踐、小結 三個方面來學習
軟件簡介
簡介
knb 全稱 Kubernetes Network Benchmark,它是一個 bash 腳本,它將在目標 Kubernetes 集群上啟動網(wǎng)絡基準測試。
參考資料:
https://github.com/InfraBuilder/k8s-bench-suite
它的主要特點如下:
依賴很少的普通 bash 腳本
完成基準測試僅需 2 分鐘
能夠僅選擇要運行的基準測試的子集
測試TCP 和 UDP帶寬
自動檢測 CNI MTU
在基準報告中包括主機 cpu 和 ram 監(jiān)控
能夠使用 plotly/orca 基于結果數(shù)據(jù)創(chuàng)建靜態(tài)圖形圖像(參見下面的示例)
無需 ssh 訪問,只需通過標準 kubectl訪問目標集群
不需要高權限,腳本只會在兩個節(jié)點上啟動非常輕量級的 Pod。
它提供了數(shù)據(jù)的圖形生成鏡像和配套的服務鏡像
準備工作
master節(jié)點下載核心服務鏡像
docker pull olegeech/k8s-bench-suite
特定node節(jié)點下載鏡像
docker pull infrabuilder/bench-custom-monitor
docker pull infrabuilder/bench-iperf3
docker pull quay.io/plotly/orca
注意事項
由于需要測試k8s節(jié)點間的網(wǎng)絡通信質量并且將結果輸出,所以它在操作的過程中需要提前做一些準備
1 準備k8s集群的認證config文件
2 準備數(shù)據(jù)文件的映射目錄
簡單實踐
命令解析文章來源:http://www.zghlxwxcb.cn/news/detail-529855.html
對于容器內(nèi)部的knb命令來說,它的基本格式如下:
knb --verbose --client-node 客戶端節(jié)點 --server-node 服務端節(jié)點
注意:
docker run時候,可以通過NODE_AUTOSELECT從集群中自動選擇幾個節(jié)點來運行測試
- 如果master節(jié)點的污點無法容忍,從而導致失敗
查看命令幫助
docker run -it --hostname knb --name knb --rm -v /tmp/my-graphs:/my-graphs -v /root/.kube/config:/.kube/config olegeech/k8s-bench-suite --help
注意:
如果網(wǎng)絡效果不是很好的話,會因為鏡像無法獲取而導致失敗,需要重試幾次即可
所以,如果可以的話,提前下載到特定的工作節(jié)點上
測試效果文章來源地址http://www.zghlxwxcb.cn/news/detail-529855.html
生成檢測數(shù)據(jù)
docker run -it --hostname knb --name knb --rm -v /tmp/my-graphs:/my-graphs -v /root/.kube/config:/.kube/config olegeech/k8s-bench-suite --verbose --server-node kubernetes-node1 --client-node kubernetes-node2 -o data -f /my-graphs/mybench.knbdata
以json方式顯示數(shù)據(jù)
docker run -it --hostname knb --name knb --rm -v /tmp/my-graphs:/my-graphs -v /root/.kube/config:/.kube/config olegeech/k8s-bench-suite -fd /my-graphs/mybench.knbdata -o json
根據(jù)數(shù)據(jù)進行繪圖展示
docker run -it --hostname knb --name knb --rm -v /tmp/my-graphs:/my-graphs -v /root/.kube/config:/.kube/config olegeech/k8s-bench-suite -fd /my-graphs/mybench.knbdata --plot --plot-dir /my-graphs/
設定數(shù)據(jù)的圖形樣式
docker run -it --hostname knb --name knb --rm -v /tmp/my-graphs:/my-graphs -v /root/.kube/config:/.kube/config olegeech/k8s-bench-suite -fd /my-graphs/mybench.knbdata --plot --plot-args '--width 900 --height 600' --plot-dir /my-graphs
到了這里,關于K8S集群安全升級(CIS CNI Calico)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!