3.2.2 K8S入門

目錄

3.2.2.1 K8S集羣架構搭建及運行docker容器

1、Linux 操作系統原理

    1.1、計算機硬件

    1.2、操作系統

    1.3、Linux操作系統

    1.4、Linux系統的操作原理

2、K8S 集羣架構圖

3、K8S 集羣部署架構

    3.1、Kubernetes的8個集羣管理能力

    3.2、在Kubernetes中,service對象的4個特徵

4、集羣環境配置說明

    4.1、環境準備

    4.2、集羣詳情、組件版本

    4.3、環境說明

    4.4、主要配置策略

5、集羣環境搭建安裝(系統初始化和全局變量)

    5.1、設置主機名、添加docker賬戶

​     5.2、設置master可以無密碼登錄所有節點的root賬戶

     5.3、將可執行文件路徑/opt/k8s/bin添加到PATH變量中

​     5.4、安裝依賴包

     5.5、關閉防火牆

      5.6、關閉swap分區

      5.7、關閉SELinux

      5.8、關閉dnsmasq(可選)

     5.9、加載內核模塊(可選)

     5.10、優化內核參數

     5.11、設置系統時區

     5.12、更新系統時間(可選)

     5.13、關閉無關的服務

     5.14、設置rsyslog和systemd journal

     5.15、創建相關目錄

      5.16、升級內核、關閉 NUMA

      5.17、檢查系統內核和模塊是否適合運行docker(僅適用於linux系統)

      5.18、分發集羣環境變量定義腳本(擴容時不需要執行該步驟)

6、HTTPS網絡安全架構設計

    6.1、對稱加密

    6.2、非對稱加密

    6.3、數組證書

    6.4、數組證書的4種格式

    6.5、4種數組證書格式相互轉換

    6.6、SSL證書

    6.7、Nginx集羣環境SSL證書部署

7、集羣環境搭建安裝(創建 CA 證書和祕鑰)

    7.1、安裝cfssl工具

    7.2、創建根證書(CA)

    7.3、分發證書文件

8、集羣環境搭建安裝(部署kubectl命令行工具) 

    8.1、下載和分發kubectl命令行工具

     8.2、創建admin證書、私鑰

     8.3、創建kubeconfig文件

      8.4、分發kubeconfig文件

3.2.2.2 K8S基於二進制集羣架構搭建1

1、部署etcd集羣

    1.1、下載和分發etcd二進制文件

    1.2、創建etcd證書和私鑰

    1.3、創建etcd的systemd unit模板文件

    1.4、爲各節點創建和分發etcd systemd unit文件

    1.5、啓動etcd服務 

    1.6、驗證服務狀態

    1.7、查看當前的leader

​2、部署flannel網絡

    2.1、下載和分發flannel二進制文件

    2.2、創建flannel證書和私鑰

     2.3、向etcd寫入集羣Pod網段信息

     2.4、創建flannel的systemd unit文件

     2.5、分發flanneld systemd unit文件到所有節點

      2.6、啓動flanneld服務

      2.7、檢查分配給各flanneld的Pod網段信息

      2.8、驗證各節點能通過Pod網段互通

3.2.2.3 K8S基於二進制集羣架構搭建2

3.2.2.4 K8S基於二進制集羣架構搭建3


3.2.2.1 K8S集羣架構搭建及運行docker容器

1、Linux 操作系統原理

參考地址:https://product.pconline.com.cn/itbk/software/dnyw/1707/9626394.html
    一個計算機系統是硬件、軟件的共生體,它們互相依賴、不可分割

    1.1、計算機硬件

        是由外圍設備、處理器、內存、硬盤和其他電子設備組成的計算機發動機

    1.2、操作系統

        是控制硬件工作的,是用來和硬件打交道,爲用戶程序提供一個有限服務集的低級支撐軟件。

    1.3、Linux操作系統

        在Linux中操作系統被稱爲“內核”,也稱爲“核心”。
        Linux內核的主要模塊(組件)分爲以下7部分:
            存儲管理
            CPU和進程管理
            文件系統
            設備管理和驅動
            網絡通信
            系統的初始化(引導)
            系統調用

        Linux內核被設計爲“單內核”(monolithic)結構

    1.4、Linux系統的操作原理

        1、一切都是文件
        2、每個軟件都有確定的用途

2、K8S 集羣架構圖

1、etcd一個高可用的K/V鍵值對存儲和服務發現系統
2、flannel實現跨主機的容器網絡的通信
3、kube-apiserver提供kubernetes集羣的API調用
4、kube-controller-manager確保集羣服務
5、kube-scheduler調度容器,分配到Node
6、kubelet在Node節點上按照配置文件中定義的容器規格 啓動容器
7、kube-proxy提供網絡代理服務 

3、K8S 集羣部署架構

1個master + 2個node。存儲集羣etcd是單點集羣(真實環境不推薦此做法,需要集羣)。網絡使用的是flannel虛擬二次網絡。

    3.1、Kubernetes的8個集羣管理能力

        1、多層次的安全防護和准入機制
        2、多租戶應用支撐能力
        3、透明的服務註冊和服務發現機制
        4、內建智能負載均衡器
        5、強大的故障發現和自我修復能力
        6、服務滾動升級和在線擴容能力
        7、可擴展的資源自動調度機制
        8、以及多粒度的資源管理能力

    3.2、在Kubernetes中,service對象的4個特徵

        1、擁有一個唯一指定的名字
            eg:mysql-service
        2、擁有一個虛擬IP和端口號
            虛擬IP:Cluster IP、service IP、VIP
        3、能夠提供某種遠程服務能力
        4、被映射到提供這種服務能力的一組容器應用上

快速、在線體驗kubernetes的功能:https://kubernetes.io/docs/tutorials/kubernetes-basics/
K8s官方下載地址:https://github.com/kubernetes

本文以下所有操作命令都參考老師的文檔:E:\meWork\study\project\subject-3\subject-3-k8s\專題三-Kubernetes_學習文檔-N.docx

4、集羣環境配置說明

    4.1、環境準備

節點

ip 地址

操作系統

master

192.168.0.32

CentOS 7.8-x86_64

node1

192.168.0.33

CentOS 7.8-x86_64

node2

192.168.0.34

CentOS 7.8-x86_64

    4.2、集羣詳情、組件版本

OS:CentOS Linux release 7.8.2003 (Core)
Kubernetes:1.12.3(最低的版本要求是1.6)
Docker:18.09.0-ce(建議使用 Docker CE)
Etcd:3.3.10
Flannel:v0.10.0 (vxlan或者host-gw 網絡)
TLS 認證通信 (所有組件,如 etcd、kubernetes master 和 node)
RBAC 授權
kubelet TLS BootStrapping
插件:Coredns、dashboardheapster(influxdb、grafana)、Metrics-Server、EFK(elasticsearch、fluentd、kibana)
鏡像倉庫:docker registry、harbor
私有docker鏡像倉庫harbor(harbor提供離線安裝包,直接使用docker-compose啓動即可)
    私有docker鏡像倉庫harbor的參官文檔:
        安裝文檔:https://github.com/goharbor/harbor/blob/master/docs/install-config/installation-prereqs.md
        配置 https訪問:https://github.com/goharbor/harbor/blob/master/docs/install-config/configure-https.md

    4.3、環境說明

Master:192.168.0.32

Node:192.168.0.33192.168.0.34

注意:192.168.0.32 這臺主機 master 和 node 複用。所有生成證書、執行 kubectl 命令的操作都在這臺節點上執行。一旦 node 加入到 kubernetes 集羣之後就不需要再登陸node節點了。

    4.4、主要配置策略

        kube-apiserver:
            1、使用節點本地nginx4層透明代理實現高可用
            2、關閉非安全端口8080和匿名訪問
            3、在安全端口6443接收https請求
            4、嚴格的認證和授權策略(x509、token、RBAC)
            5、開啓bootstrap token認證,支持kubelet TLS bootstrapping
            6、使用https訪問kubelet、etcd,加密通信
        kube-controller-manager:
            1、3節點高可用
            2、關閉非安全端口,在安全端口10252接收https請求
            3、使用kubeconfig訪問apiserver的安全端口
            4、自動approve kubelet證書籤名請求(CSR),證書過期後自動輪轉
            5、各controller使用自己的ServiceAccount訪問apiserver
        kube-scheduler:
            1、3節點高可用
            2、使用kubeconfig訪問apiserver的安全端口
        kubelet:
            1、使用kubeadm動態創建bootstrap token,而不是在apiserver中靜態配置
            2、使用TLS bootstrap機制自動生成client和server證書,過期後自動輪轉
            3、在KubeletConfiguration類型的JSON文件配置主要參數
            4、關閉只讀端口,在安全端口10250接收https請求,對請求進行認證和授權,拒絕匿名訪問和非授權訪問
            5、使用kubeconfig訪問apiserver的安全端口
        kube-proxy:
            1、使用kubeconfig訪問apiserver的安全端口
            2、在KubeProxyConfiguration類型的JSON文件配置主要參數
            3、使用ipvs代理模式
        集羣插件:
            DNS:使用功能、性能更好的 coredns
            Dashboard:支持登錄認證
            Metric:heapster、metrics-server,使用https訪問kubelet安全端口
            Log:Elasticsearch、Fluend、Kibana
            Registry 鏡像庫:docker-registry、harbor

harbor私有鏡像倉庫:參考:https://github.com/goharbor/harbor

5、集羣環境搭建安裝(系統初始化和全局變量)

“5.3”到“5.17”的命令在master、node1、node2,3臺機器上都需要執行

    5.1、設置主機名、添加docker賬戶

設置永久主機名稱,然後xshell重新連接,就可以看到名稱變成新的名稱了

1、將主機名改爲masterhostnamectl set-hostname master

2、爲支持DNS解析主機名稱,修改/etc/hosts文件:
cat >> /etc/hosts <<EOF
192.168.0.32 master master
192.168.0.33 node1 node1
192.168.0.34 node2 node2
EOF

3、添加docker賬戶:useradd -m docker


     5.2、設置master可以無密碼登錄所有節點的root賬戶

1、創建一個rsa的密鑰:ssh-keygen -t rsa
2、將公鑰文件放到master的root賬戶下:ssh-copy-id root@master
3、將公鑰文件放到node1的root賬戶下:ssh-copy-id root@node1
4、將公鑰文件放到node2的root賬戶下:ssh-copy-id root@node2

5、遠程連接到node1上去:ssh root@node1

     5.3、將可執行文件路徑/opt/k8s/bin添加到PATH變量中

後面會將k8s可執行組件的二進制文件,全部放到/opt/k8s/bin目錄下,以這個目錄作爲標準。
爲了執行命令時不用寫全路徑,需要將這個路添加到PATH變量中
1、添加環境變量:echo 'PATH=/opt/k8s/bin:$PATH' >>/root/.bashrc
2、查看是否添加成功:cat /root/.bashrc

     5.4、安裝依賴包

在master、node1、node2都需要執行下面3個命令
1、安裝依賴包1:yum install -y epel-release
2、安裝依賴包2:yum install -y conntrack ntpdate ntp ipvsadm ipset jq iptables curl sysstat libseccomp wget
3、安裝完畢後,檢查ip_vs是否正常:/usr/sbin/modprobe ip_vs

     5.5、關閉防火牆

從“4.4、主要配置策略”可以知道需要用到很多端口,爲了方便(避免每一個端點都在防火牆中配置放行),避免少配置了端口,導致安裝失敗,所以需要關閉防火牆。

1、關閉防火牆:systemctl stop firewalld
2、取消防火牆的自啓動:systemctl disable firewalld
3、清除防火牆的規則策略1:iptables -F && iptables -X && iptables -F -t nat && iptables -X -t nat
   清除防火牆的規則策略2:iptables -P FORWARD ACCEPT

      5.6、關閉swap分區

如果開啓了swap分區,kubelet會啓動失敗
1、關閉swap分區:swapoff -a
2、註釋/etc/fstab中swap的相應行:sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

      5.7、關閉SELinux

SELinux是linux內核的保護,如果開啓SELinux,執行某些受保護的命令就會報錯:Permission denied
1、關閉SELinux的命令1:setenforce 0
2、關閉SELinux的命令2:sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config

      5.8、關閉dnsmasq(可選)

linux系統開啓了dnsmasq後(eg:GUI環境),將系統DNS Server設置爲 127.0.0.1,這會導致docker容器無法解析域名,需要關閉它:

systemctl stop dnsmasq

systemctl disable dnsmasq

     5.9、加載內核模塊(可選)

如果是比較老的版本,就需要執行這個命令,新的版本就不用執行

modprobe ip_vs_rr

modprobe br_netfilter

     5.10、優化內核參數

這一步如果執行有一些報錯不用理會,繼續往下執行。(因爲版本不一樣,參數值有可能也不一樣)

1、創建kubernetes.conf命令:
cat > kubernetes.conf <<EOF
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv4.ip_forward=1
net.ipv4.tcp_tw_recycle=0
vm.swappiness=0 # 禁止使用 swap 空間,只有當系統 OOM 時才允許使用它
vm.overcommit_memory=1 # 不檢查物理內存是否夠用
vm.panic_on_oom=0 # 開啓 OOM
fs.inotify.max_user_instances=8192
fs.inotify.max_user_watches=1048576
fs.file-max=52706963
fs.nr_open=52706963
net.ipv6.conf.all.disable_ipv6=1
net.netfilter.nf_conntrack_max=2310720
EOF

2、複製kubernetes.conf到/etc/sysctl.d下:cp kubernetes.conf  /etc/sysctl.d/kubernetes.conf
3、是/etc/sysctl.d/kubernetes.conf文件生效:sysctl -p /etc/sysctl.d/kubernetes.conf

     5.11、設置系統時區

#1、調整系統TimeZone
timedatectl set-timezone Asia/Shanghai
#2、將當前的UTC時間寫入硬件時鐘
timedatectl set-local-rtc 0
#3、重啓依賴於系統時間的服務
systemctl restart rsyslog 
systemctl restart crond

     5.12、更新系統時間(可選)

ntpdate cn.pool.ntp.org

     5.13、關閉無關的服務

systemctl stop postfix && systemctl disable postfix

     5.14、設置rsyslog和systemd journal

systemd的journald 記錄日誌的3個優勢:
    1、可以記錄到內存或文件系統(默認記錄到內存,對應的位置爲/run/log/jounal)
    2、可以限制佔用的磁盤空間、保證磁盤剩餘空間
    3、可以限制日誌文件大小、保存的時間

由於journald默認將日誌轉發給rsyslog,這會導致:
    1、日誌寫了多份
    2、/var/log/messages中包含了太多無關日誌,不方便後續查看
    3、同時也影響系統性能

因爲上面的問題,所以需要修改默認設置

#1、持久化保存日誌的目錄
mkdir /var/log/journal
mkdir /etc/systemd/journald.conf.d
cat > /etc/systemd/journald.conf.d/99-prophet.conf <<EOF
[Journal]

#2、持久化保存到磁盤
Storage=persistent

#3、壓縮歷史日誌
Compress=yes

SyncIntervalSec=5m
RateLimitInterval=30s
RateLimitBurst=1000

#4、最大佔用空間10G
SystemMaxUse=10G

#5、單日誌文件最大200M
SystemMaxFileSize=200M

#6、日誌保存時間2周
MaxRetentionSec=2week

#7、不將日誌轉發到syslog
ForwardToSyslog=no
EOF
systemctl restart systemd-journald

     5.15、創建相關目錄

mkdir -p /opt/k8s/{bin,work} /opt/k8s/work/cert /etc/{kubernetes,etcd}/cert

      5.16、升級內核、關閉 NUMA

系統內核是3.10以下版本需要才需要升級內核、關閉 NUMA
查看系統內核版本:uname -a

      5.17、檢查系統內核和模塊是否適合運行docker(僅適用於linux系統)

1、下載check-config.sh文件:curl https://raw.githubusercontent.com/docker/docker/master/contrib/check-config.sh > check-config.sh

我下載不了,直接用的老師給的check-config.sh文件,上傳到虛擬機中,直接執行bash ./check-config.sh命令,也可以

2、bash ./check-config.sh

      5.18、分發集羣環境變量定義腳本(擴容時不需要執行該步驟)

3個節點收執行這個命令,便於直接拖拽文件到xshell,上傳到虛擬機對應目錄。文件拖拽上傳、下載的工具

yum install -y lrzsz

後續的部署步驟將使用environment.sh文件中定義的全局環境變量;
老師提供的文件在:http://59.111.92.219/q1906-java/subject-3/blob/master/subject-3-k8s/environment.sh

下面的命令只在master節點執行

根據自己的機器情況修改文件內容,然後將文件複製到所有節點的/opt/k8s/bin目錄
export IFACE的就是IP配置文件的DEVICE值(查看網絡接口名稱):vim /etc/sysconfig/network-scripts/ifcfg-enp0s3

變成可執行文件:chmod +x environment.sh 
讓環境變量文件生效:source environment.sh 

 讀取環境變量文件,然後分發到其他節點:

for node_ip in ${NODE_IPS[@]}

  do

    echo ">>> ${node_ip}"

    scp /opt/k8s/bin/environment.sh root@${node_ip}:/opt/k8s/bin/

    ssh root@${node_ip} "chmod +x /opt/k8s/bin/*"

  done

6、HTTPS網絡安全架構設計

    6.1、對稱加密

        “明文”通過“密鑰”加密成“密文”;拿到“密文”,需要通過“密鑰”解密成“明文”
    常見的對稱加密算法有:DES、3DES、AES、Blowfish、IDEA、RC5、RC6

    6.2、非對稱加密

        用“公鑰”對“明文”加密,用“私鑰”對“明文”解密
    常見的非對稱加密算法有:RSA、Elagmal、揹包算法、Rabin
    應用場景:SSH、HTTPS、TLS、電子證書、電子簽名、電子身份證......

    6.3、數組證書

    數字證書就是識別網站(服務器)

    6.4、數組證書的4種格式

    1、Java Keystore(JKS)格式
        這是Java提供的密碼庫,通過Java Development Kit(JDK)工具包中的Keytool工具,生成Java Keystore(JKS)格式的證書文件。
            使用這個格式的軟件有:Tomcat、Weblogic、JBoss
    2、PEM、KEY、CRT格式
        這是OpenSSl工具提供的密碼庫,生成PEM、KEY、CRT等格式的證書文件    
            使用這個格式的軟件有:Apache、Nginx
    3、KDB格式
        這是使用IBM產品自帶的iKeyman工具,生成KDB格式的證書文件。
            使用這個格式的軟件是IBM的Web服務產品,eg:Websphere、IBM Http Server(IHS)
    4、PFX格式
        這是使用Windows自帶的證書庫生成PFX格式的證書
            使用這個格式的服務有:微軟Windows Server中的Internet Information Services(IIS)服務

只有經過CA簽發後才能得到真正的證書,詳細瞭解數字證書:https://www.jianshu.com/p/42bf7c4d6ab8

    6.5、4種數組證書格式相互轉換

 

    6.6、SSL證書

 SSL證書是數字證書的一種方式

SSLSecure Socket Layer安全套接字協議,提供兩個安全服務:鑑別、保密

HTTPS就是HTTP的安全版,HTTP下加入SSL層


HTTPS協議主要作用:
    1、建立一個信息安全通道,來保證數據傳輸的安全
    2、確認網站的真實性

SSL/TLS:安全套接字協議(SSL)是Web瀏覽器與Web服務器之間安全交換信息的協議。

用於網站HTTPS化的SSL數字證書有3種類型:DV SSL(個人)、OV SSL(組織、企業)、EV SSL(大型企業、金融機構)

 

SSL證書的優勢:
    1、簡單快捷
        只需要申請一張證書,部署在服務器上,就可以在有效期內不用做其他操作
    2、顯示直觀
        部署SSL證書後,通過https訪問網站,能在地址欄或地址欄右側直接看到加密鎖標誌。
    3、身份認證
        能在證書信息裏看到網站所有者公司信息,進而確認網站的有效性和真實性。 

    6.7、Nginx集羣環境SSL證書部署

證書部署在Nginx上,在nginx.conf配置文件中加入如下配置:

7、集羣環境搭建安裝(創建 CA 證書和祕鑰)

爲確保安全,kubernetes系統各組件需要使用x509證書對通信進行加密和認證。
CA(Certificate Authority)是自簽名的根證書,用來簽名後續創建的其它證書。
本文檔使用CloudFlare的PKI工具集cfssl創建所有證書
cfssl的github地址:https://github.com/cloudflare/cfssl

    7.1、安裝cfssl工具

進入work目錄:cd /opt/k8s/work
變成可執行文件:chmod +x /opt/k8s/bin/*

    7.2、創建根證書(CA)

        CA證書是集羣所有節點共享的,只需要創建一個CA證書,後續創建的所有證書都由它簽名。

第一步、創建配置文件CA配置文件:用於配置根證書的使用場景(profiles)和具體參數,後續在簽名其它證書時需要指定特定場景。
    具體參數有:usage,過期時間、服務端認證、客戶端認證、加密等
    signing:表示該證書可用於簽名其它證書,生成的ca.pem證書中CA=TRUE;
    server auth:表示client可以用該該證書對server提供的證書進行驗證;
    client auth:表示server可以用該該證書對client提供的證書進行驗證;
cat > ca-config.json <<EOF
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "kubernetes": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ],
        "expiry": "87600h"
      }
    }
  }
}
EOF

第二步、創建證書籤名請求文件 

CN:Common Name,kube-apiserver從證書中提取該字段作爲請求的用戶名(User Name),瀏覽器使用該字段驗證網站是否合法;
O:Organization,kube-apiserver從證書中提取該字段作爲請求用戶所屬的組(Group);
kube-apiserver將提取的User、Group作爲RBAC授權的用戶標識;

第三步、生成CA證書、私鑰 

    7.3、分發證書文件

將生成的CA證書、祕鑰文件、配置文件拷貝到所有節點的/etc/kubernetes/cert目錄下:

source /opt/k8s/bin/environment.sh # 導入 NODE_IPS 環境變量

for node_ip in ${NODE_IPS[@]}

  do

    echo ">>> ${node_ip}"

    ssh root@${node_ip} "mkdir -p /etc/kubernetes/cert"

    scp ca*.pem ca-config.json root@${node_ip}:/etc/kubernetes/cert

  done

8、集羣環境搭建安裝(部署kubectl命令行工具) 

    8.1、下載和分發kubectl命令行工具

將如下文件拖拽上傳到work目錄

     8.2、創建admin證書、私鑰

kubectl是kubernetes集羣的命令行管理工具。
kubectl與apiserver https安全端口通信,apiserver對提供的證書進行認證和授權。
kubectl作爲集羣的管理工具,需要被授予最高權限。這裏創建具有最高權限的admin證書。
第一步、創建證書籤名請求
cat > admin-csr.json <<EOF
{
  "CN": "admin",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "system:masters",
      "OU": "study163"
    }
  ]
}
EOF

system:masters:kube-apiserver收到該證書後,將請求的Group設置爲system:masters;
預定義的ClusterRoleBinding cluster-admin將Group system:masters與Role cluster-admin綁定,該Role授予所有API的權限;
該證書只會被kubectl當做client證書使用,所以hosts字段爲空; 

 
第二步、生成證書和私鑰

 cfssl gencert -ca=/opt/k8s/work/cert/ca.pem \

  -ca-key=/opt/k8s/work/cert/ca-key.pem \

  -config=/opt/k8s/work/cert/ca-config.json \

  -profile=kubernetes admin-csr.json | cfssljson -bare admin

     8.3、創建kubeconfig文件

kubeconfig爲kubectl的配置文件,包含訪問apiserver的所有信息,eg:apiserver地址、CA證書、自身使用的證書

命令如下:

source /opt/k8s/bin/environment.sh

# 設置集羣參數
kubectl config set-cluster kubernetes \
  --certificate-authority=/opt/k8s/work/cert/ca.pem \
  --embed-certs=true \
  --server=${KUBE_APISERVER} \
  --kubeconfig=kubectl.kubeconfig

# 設置客戶端認證參數
kubectl config set-credentials admin \
  --client-certificate=/opt/k8s/work/cert/admin.pem \
  --client-key=/opt/k8s/work/cert/admin-key.pem \
  --embed-certs=true \
  --kubeconfig=kubectl.kubeconfig

# 設置上下文參數
kubectl config set-context kubernetes \
  --cluster=kubernetes \
  --user=admin \
  --kubeconfig=kubectl.kubeconfig

# 設置默認上下文
kubectl config use-context kubernetes --kubeconfig=kubectl.kubeconfig

certificate-authority:驗證kube-apiserver證書的根證書;
client-certificate、--client-key:剛生成的admin證書、私鑰,連接kube-apiserver時使用;
embed-certs=true:將ca.pem和admin.pem證書內容嵌入到生成的kubectl.kubeconfig文件中(不加時,寫入的是證書文件路徑);

      8.4、分發kubeconfig文件

分發到所有使用kubectl命令的節點:
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    ssh root@${node_ip} "mkdir -p ~/.kube"
    scp kubectl.kubeconfig root@${node_ip}:~/.kube/config
  done

3.2.2.2 K8S基於二進制集羣架構搭建1

1、部署etcd集羣

    etcd是基於Raft的分佈式key-value存儲系統,常用於:服務發現、共享配置、併發控制(leader選舉、分佈式鎖)。
etcd集羣各節點的名稱和IP如下:
        master:192.168.0.32
        node1:192.168.0.33
        node2:192.168.0.34

    1.1、下載和分發etcd二進制文件

前面已經將etcd的包上傳到work目錄,不需要再下載了 

分發二進制文件到集羣所有節點:

source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    scp etcd-v3.3.10-linux-amd64/etcd* root@${node_ip}:/opt/k8s/bin
    ssh root@${node_ip} "chmod +x /opt/k8s/bin/*"
  done

    1.2、創建etcd證書和私鑰

第一步、創建證書籤名請求

cd /opt/k8s/work/cert

cat > etcd-csr.json <<EOF
{
  "CN": "etcd",
  "hosts": [
    "127.0.0.1",
    "192.168.0.32",
    "192.168.0.33",
    "192.168.0.34"
  ],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "study163"
    }
  ]
}
EOF

hosts:指定授權使用該證書的etcd節點IP或域名列表,這裏將etcd集羣的三個節點IP都列在其中

第二步、生成證書、私鑰

cfssl gencert -ca=/opt/k8s/work/cert/ca.pem \
    -ca-key=/opt/k8s/work/cert/ca-key.pem \
    -config=/opt/k8s/work/cert/ca-config.json \
    -profile=kubernetes etcd-csr.json | cfssljson -bare etcd

第三步、分發生成的證書和私鑰到各etcd節點

source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    ssh root@${node_ip} "mkdir -p /etc/etcd/cert"
    scp etcd*.pem root@${node_ip}:/etc/etcd/cert/
  done

    1.3、創建etcd的systemd unit模板文件

cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
cat > etcd.service.template <<EOF
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
Documentation=https://github.com/coreos

[Service]
Type=notify
WorkingDirectory=${ETCD_DATA_DIR}
ExecStart=/opt/k8s/bin/etcd \\
  --data-dir=${ETCD_DATA_DIR} \\
  --wal-dir=${ETCD_WAL_DIR} \\
  --name=##NODE_NAME## \\
  --cert-file=/etc/etcd/cert/etcd.pem \\
  --key-file=/etc/etcd/cert/etcd-key.pem \\
  --trusted-ca-file=/etc/kubernetes/cert/ca.pem \\
  --peer-cert-file=/etc/etcd/cert/etcd.pem \\
  --peer-key-file=/etc/etcd/cert/etcd-key.pem \\
  --peer-trusted-ca-file=/etc/kubernetes/cert/ca.pem \\
  --peer-client-cert-auth \\
  --client-cert-auth \\
  --listen-peer-urls=https://##NODE_IP##:2380 \\
  --initial-advertise-peer-urls=https://##NODE_IP##:2380 \\
  --listen-client-urls=https://##NODE_IP##:2379,http://127.0.0.1:2379 \\
  --advertise-client-urls=https://##NODE_IP##:2379 \\
  --initial-cluster-token=etcd-cluster-0 \\
  --initial-cluster=${ETCD_NODES} \\
  --initial-cluster-state=new \\
  --auto-compaction-mode=periodic \\
  --auto-compaction-retention=1 \\
  --max-request-bytes=33554432 \\
  --quota-backend-bytes=6442450944 \\
  --heartbeat-interval=250 \\
  --election-timeout=2000
Restart=on-failure
RestartSec=5
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

WorkingDirectory、--data-dir:指定工作目錄和數據目錄爲${ETCD_DATA_DIR},需在啓動服務前創建這個目錄;
--wal-dir:指定wal目錄,爲了提高性能,一般使用SSD或者和--data-dir不同的磁盤;
--name:指定節點名稱,當--initial-cluster-state值爲new時,--name的參數值必須位於--initial-cluster列表中;
--cert-file、--key-file:etcd server與client通信時使用的證書和私鑰;
--trusted-ca-file:簽名client證書的CA證書,用於驗證client證書;
--peer-cert-file、--peer-key-file:etcd與peer通信使用的證書和私鑰;
--peer-trusted-ca-file:簽名peer證書的CA證書,用於驗證peer證書;

    1.4、爲各節點創建和分發etcd systemd unit文件

第一步、替換模板文件中的變量,爲各節點創建systemd unit文件

NODE_NAMES和NODE_IPS爲相同長度的bash數組,分別爲節點名稱和對應的IP

source /opt/k8s/bin/environment.sh
for (( i=0; i < 3; i++ ))
  do
    sed -e "s/##NODE_NAME##/${NODE_NAMES[i]}/" -e "s/##NODE_IP##/${NODE_IPS[i]}/" etcd.service.template > etcd-${NODE_IPS[i]}.service 
  done

第二步、分發生成的systemd unit文件

文件重命名爲 etcd.service

source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    scp etcd-${node_ip}.service root@${node_ip}:/usr/lib/systemd/system/etcd.service
  done

    1.5、啓動etcd服務 

    1、必須創建etcd數據目錄和工作目錄;
    2、etcd進程首次啓動時會等待其它節點的etcd加入集羣,命令systemctl start etcd會卡住一段時間,爲正常現象

第一步、啓動etcd服務

cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    ssh root@${node_ip} "mkdir -p ${ETCD_DATA_DIR} ${ETCD_WAL_DIR}"
    ssh root@${node_ip} "systemctl daemon-reload && systemctl enable etcd && systemctl restart etcd " &
  done

第二步、檢查啓動結果

新開一個xshell窗口,運行如下命令,如果都是active (running),就說明已經啓動正常了,直接在啓動的窗口回車即可。

cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    ssh root@${node_ip} "systemctl status etcd|grep Active"
  done

如果狀態不是爲active(running),就查看日誌,確認原因:journalctl -u etcd

    1.6、驗證服務狀態

cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    ETCDCTL_API=3 /opt/k8s/bin/etcdctl \
    --endpoints=https://${node_ip}:2379 \
    --cacert=/opt/k8s/work/cert/ca.pem \
    --cert=/etc/etcd/cert/etcd.pem \
    --key=/etc/etcd/cert/etcd-key.pem endpoint health
  done

    1.7、查看當前的leader

source /opt/k8s/bin/environment.sh
ETCDCTL_API=3 /opt/k8s/bin/etcdctl \
  -w table --cacert=/opt/k8s/work/cert/ca.pem \
  --cert=/etc/etcd/cert/etcd.pem \
  --key=/etc/etcd/cert/etcd-key.pem \
  --endpoints=${ETCD_ENDPOINTS} endpoint status

2、部署flannel網絡

    flannel是二次虛擬技術網絡,在物理網絡、docker網絡進行了一次虛擬化,節點中的docker容器的Pod之間進行相互通信。

    2.1、下載和分發flannel二進制文件

前面已經將flannel的包上傳到work目錄,不需要再下載了 

1、創建flannel文件夾:mkdir flannel
2、解壓flannel並放入flannel文件夾中:tar -xzvf flannel-v0.10.0-linux-amd64.tar.gz -C flannel

3、分發flannel二進制文件到集羣所有節點

cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    scp flannel/{flanneld,mk-docker-opts.sh} root@${node_ip}:/opt/k8s/bin/
    ssh root@${node_ip} "chmod +x /opt/k8s/bin/*"
  done

    2.2、創建flannel證書和私鑰

flannel從etcd集羣存取網段分配信息,而etcd集羣啓用了雙向x509證書認證,所以需要爲flanneld生成證書和私鑰。

第一步、創建證書籤名請求 

該證書只會被kubectl當做client證書使用,所以hosts字段爲空(不需要做主機驗證)

cd /opt/k8s/work/cert
cat > flanneld-csr.json <<EOF
{
  "CN": "flanneld",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "study163"
    }
  ]
}
EOF

第二步、生成證書和私鑰 

cfssl gencert -ca=/opt/k8s/work/cert/ca.pem \
  -ca-key=/opt/k8s/work/cert/ca-key.pem \
  -config=/opt/k8s/work/cert/ca-config.json \
  -profile=kubernetes flanneld-csr.json | cfssljson -bare flanneld
ls flannel*pem

 第三步、將生成的證書和私鑰分發到所有節點

cd /opt/k8s/work/cert
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    ssh root@${node_ip} "mkdir -p /etc/flanneld/cert"
    scp flanneld*.pem root@${node_ip}:/etc/flanneld/cert
  done

     2.3、向etcd寫入集羣Pod網段信息

注意:本步驟只需執行一次

1、flannel當前版本(v0.10.0)不支持etcd v3,故使用etcd v2 API寫入配置key和網段數據;

2、寫入的Pod網段${CLUSTER_CIDR}地址段如/16必須小於SubnetLen,必須與kube-controller-manager的--cluster-cidr參數值一致;

cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
etcdctl \
  --endpoints=${ETCD_ENDPOINTS} \
  --ca-file=/opt/k8s/work/cert/ca.pem \
  --cert-file=/opt/k8s/work/cert/flanneld.pem \
  --key-file=/opt/k8s/work/cert/flanneld-key.pem \
  set ${FLANNEL_ETCD_PREFIX}/config '{"Network":"'${CLUSTER_CIDR}'", "SubnetLen": 21, "Backend": {"Type": "vxlan"}}'

     2.4、創建flannel的systemd unit文件

mk-docker-opts.sh:腳本將分配給flanneld的Pod子網網段信息寫入/run/flannel/docker文件,
                                   後續docker啓動時使用這個文件中的環境變量配置docker0網橋;
flanneld:使用系統缺省路由所在的接口與其它節點通信,對於有多個網絡接口(如內網和公網)的節點,
                 可以用-iface參數指定通信接口;
flanneld:運行時需要root權限;
-ip-masq: flanneld爲訪問Pod網絡外的流量設置SNAT規則,同時將傳遞給Docker的變量--ip-masq(/run/flannel/docker 文件中)
                 設置爲false,這樣Docker將不再創建SNAT規則;Docker的--ip-masq爲true時,
                        創建的SNAT規則比較“暴力”:將所有本節點Pod發起的、訪問非docker0接口的請求做SNAT,
                                                                      這樣訪問其他節點Pod的請求來源IP會被設置爲flannel.1接口的IP,
                                                                      導致目的Pod看不到真實的來源Pod IP。flanneld創建的SNAT規則比較溫和,
                                                                     只對訪問非Pod網段的請求做SNAT。

cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
cat > flanneld.service << EOF
[Unit]
Description=Flanneld overlay address etcd agent
After=network.target
After=network-online.target
Wants=network-online.target
After=etcd.service
Before=docker.service

[Service]
Type=notify
ExecStart=/opt/k8s/bin/flanneld \\
  -etcd-cafile=/etc/kubernetes/cert/ca.pem \\
  -etcd-certfile=/etc/flanneld/cert/flanneld.pem \\
  -etcd-keyfile=/etc/flanneld/cert/flanneld-key.pem \\
  -etcd-endpoints=${ETCD_ENDPOINTS} \\
  -etcd-prefix=${FLANNEL_ETCD_PREFIX} \\
  -iface=${IFACE} \\
  -ip-masq
ExecStartPost=/opt/k8s/bin/mk-docker-opts.sh -k DOCKER_NETWORK_OPTIONS -d /run/flannel/docker
Restart=always
RestartSec=5
StartLimitInterval=0

[Install]
WantedBy=multi-user.target
RequiredBy=docker.service
EOF

     2.5、分發flanneld systemd unit文件到所有節點

source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    scp flanneld.service root@${node_ip}:/usr/lib/systemd/system/
  done

      2.6、啓動flanneld服務

1、啓動flanneld服務

source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    ssh root@${node_ip} "systemctl daemon-reload && systemctl enable flanneld && systemctl restart flanneld"
  done

2、檢查啓動結果

source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    ssh root@${node_ip} "systemctl status flanneld|grep Active"
  done

如果狀態不是爲active(running),就查看日誌,確認原因:journalctl -u etcd

      2.7、檢查分配給各flanneld的Pod網段信息

1、查看集羣Pod網段(/16):

source /opt/k8s/bin/environment.sh
etcdctl \
  --endpoints=${ETCD_ENDPOINTS} \
  --ca-file=/etc/kubernetes/cert/ca.pem \
  --cert-file=/etc/flanneld/cert/flanneld.pem \
  --key-file=/etc/flanneld/cert/flanneld-key.pem \
  get ${FLANNEL_ETCD_PREFIX}/config

2、查看已分配的Pod子網段列表(/24):

source /opt/k8s/bin/environment.sh
etcdctl \
  --endpoints=${ETCD_ENDPOINTS} \
  --ca-file=/etc/kubernetes/cert/ca.pem \
  --cert-file=/etc/flanneld/cert/flanneld.pem \
  --key-file=/etc/flanneld/cert/flanneld-key.pem \
  ls ${FLANNEL_ETCD_PREFIX}/subnets

3、查看某一Pod網段對應的節點IP和flannel接口地址:

source /opt/k8s/bin/environment.sh
etcdctl \
  --endpoints=${ETCD_ENDPOINTS} \
  --ca-file=/etc/kubernetes/cert/ca.pem \
  --cert-file=/etc/flanneld/cert/flanneld.pem \
  --key-file=/etc/flanneld/cert/flanneld-key.pem \
  get ${FLANNEL_ETCD_PREFIX}/subnets/172.30.16.0-21

從輸出結果中可以看出:

1、172.30.16.0/21被分配給節點master(192.168.0.32);
2、VtepMAC爲master節點的flannel.1網卡MAC地址

      2.8、驗證各節點能通過Pod網段互通

source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    ssh ${node_ip} "/usr/sbin/ip addr show flannel.1|grep -w inet"
  done

 在各節點上ping所有flannel接口IP,確保能通:

下面的ip是“查看已分配的Pod子網段列表”中的ip
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    ssh ${node_ip} "ping -c 1 172.30.16.0"
    ssh ${node_ip} "ping -c 1 172.30.72.0"
    ssh ${node_ip} "ping -c 1 172.30.232.0"
  done
 

3.2.2.3 K8S基於二進制集羣架構搭建2

待續

3.2.2.4 K8S基於二進制集羣架構搭建3

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章