k8s系列04-kubeadm部署cilium網絡的k8s集群

本文主要在centos7系統上基于dockercilium組件部署v1.23.6版本的k8s原生集群,由于集群主要用于自己平時學習和測試使用,加上資源有限,暫不涉及高可用部署。

此前寫的一些關于k8s基礎知識和集群搭建的一些方案,有需要的同學可以看一下。

1、準備工作

1.1 cilium-集群節點信息

機器均為8C8G的虛擬機,硬盤為100G。

IP Hostname
10.31.188.1 tiny-cilium-master-188-1.k8s.tcinternal
10.31.188.11 tiny-cilium-worker-188-11.k8s.tcinternal
10.31.188.12 tiny-cilium-worker-188-12.k8s.tcinternal
10.188.0.0/18 serviceSubnet

1.2 檢查mac和product_uuid

同一個k8s集群內的所有節點需要確保mac地址和product_uuid均唯一,開始集群初始化之前需要檢查相關信息

# 檢查mac地址
ip link 
ifconfig -a

# 檢查product_uuid
sudo cat /sys/class/dmi/id/product_uuid

1.3 配置ssh免密登錄(可選)

如果k8s集群的節點有多個網卡,確保每個節點能通過正確的網卡互聯訪問

# 在root用戶下面生成一個公用的key,并配置可以使用該key免密登錄
su root
ssh-keygen
cd /root/.ssh/
cat id_rsa.pub >> authorized_keys
chmod 600 authorized_keys


cat >> ~/.ssh/config <<EOF
Host tiny-cilium-master-188-1.k8s.tcinternal
    HostName 10.31.188.1
    User root
    Port 22
    IdentityFile ~/.ssh/id_rsa

Host tiny-cilium-worker-188-11.k8s.tcinternal
    HostName 10.31.188.11
    User root
    Port 22
    IdentityFile ~/.ssh/id_rsa

Host tiny-cilium-worker-188-12.k8s.tcinternal
    HostName 10.31.188.12
    User root
    Port 22
    IdentityFile ~/.ssh/id_rsa
EOF

1.4 修改hosts文件

cat >> /etc/hosts <<EOF
10.31.188.1  tiny-cilium-master-188-1 tiny-cilium-master-188-1.k8s.tcinternal
10.31.188.11 tiny-cilium-worker-188-11 tiny-cilium-worker-188-11.k8s.tcinternal
10.31.188.12 tiny-cilium-worker-188-12 tiny-cilium-worker-188-12.k8s.tcinternal
EOF

1.5 關閉swap內存

# 使用命令直接關閉swap內存
swapoff -a
# 修改fstab文件禁止開機自動掛載swap分區
sed -i '/swap / s/^\(.*\)$/#\1/g' /etc/fstab

1.6 配置時間同步

這里可以根據自己的習慣選擇ntp或者是chrony同步均可,同步的時間源服務器可以選擇阿里云的ntp1.aliyun.com或者是國家時間中心的ntp.ntsc.ac.cn

使用ntp同步

# 使用yum安裝ntpdate工具
yum install ntpdate -y

# 使用國家時間中心的源同步時間
ntpdate ntp.ntsc.ac.cn

# 最后查看一下時間
hwclock

使用chrony同步

# 使用yum安裝chrony
yum install chrony -y

# 設置開機啟動并開啟chony并查看運行狀態
systemctl enable chronyd.service
systemctl start chronyd.service
systemctl status chronyd.service

# 當然也可以自定義時間服務器
vim /etc/chrony.conf

# 修改前
$ grep server /etc/chrony.conf
# Use public servers from the pool.ntp.org project.
server 0.centos.pool.ntp.org iburst
server 1.centos.pool.ntp.org iburst
server 2.centos.pool.ntp.org iburst
server 3.centos.pool.ntp.org iburst

# 修改后
$ grep server /etc/chrony.conf
# Use public servers from the pool.ntp.org project.
server ntp.ntsc.ac.cn iburst

# 重啟服務使配置文件生效
systemctl restart chronyd.service

# 查看chrony的ntp服務器狀態
chronyc sourcestats -v
chronyc sources -v

1.7 關閉selinux

# 使用命令直接關閉
setenforce 0

# 也可以直接修改/etc/selinux/config文件
sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config

1.8 配置防火墻

k8s集群之間通信和服務暴露需要使用較多端口,為了方便,直接禁用防火墻

# centos7使用systemctl禁用默認的firewalld服務
systemctl disable firewalld.service

1.9 配置netfilter參數

這里主要是需要配置內核加載br_netfilteriptables放行ipv6ipv4的流量,確保集群內的容器能夠正常通信。

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sudo sysctl --system

1.10 關閉IPV6(不建議)

和之前部署其他的CNI不一樣,cilium很多服務監聽默認情況下都是雙棧的(使用cilium-cli操作的時候),因此建議開啟系統的IPV6網絡支持(即使沒有可用的IPV6路由也可以)

當然沒有ipv6網絡也是可以的,只是在使用cilium-cli的一些開啟port-forward命令時會報錯而已。

# 直接在內核中添加ipv6禁用參數
grubby --update-kernel=ALL --args=ipv6.disable=1

1.11 配置IPVS(建議)

IPVS是專門設計用來應對負載均衡場景的組件,kube-proxy 中的 IPVS 實現通過減少對 iptables 的使用來增加可擴展性。在 iptables 輸入鏈中不使用 PREROUTING,而是創建一個假的接口,叫做 kube-ipvs0,當k8s集群中的負載均衡配置變多的時候,IPVS能實現比iptables更高效的轉發性能。

因為cilium需要升級系統內核,因此這里的內核版本高于4.19

注意在4.19之后的內核版本中使用nf_conntrack模塊來替換了原有的nf_conntrack_ipv4模塊

(Notes: use nf_conntrack instead of nf_conntrack_ipv4 for Linux kernel 4.19 and later)

# 在使用ipvs模式之前確保安裝了ipset和ipvsadm
sudo yum install ipset ipvsadm -y

# 手動加載ipvs相關模塊
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack

# 配置開機自動加載ipvs相關模塊
cat <<EOF | sudo tee /etc/modules-load.d/ipvs.conf
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack
EOF

sudo sysctl --system
# 最好重啟一遍系統確定是否生效

$ lsmod | grep -e ip_vs -e nf_conntrack
nf_conntrack_netlink    49152  0
nfnetlink              20480  2 nf_conntrack_netlink
ip_vs_sh               16384  0
ip_vs_wrr              16384  0
ip_vs_rr               16384  0
ip_vs                 159744  6 ip_vs_rr,ip_vs_sh,ip_vs_wrr
nf_conntrack          159744  5 xt_conntrack,nf_nat,nf_conntrack_netlink,xt_MASQUERADE,ip_vs
nf_defrag_ipv4         16384  1 nf_conntrack
nf_defrag_ipv6         24576  2 nf_conntrack,ip_vs
libcrc32c              16384  4 nf_conntrack,nf_nat,xfs,ip_vs
$ cut -f1 -d " "  /proc/modules | grep -e ip_vs -e nf_conntrack
nf_conntrack_netlink
ip_vs_sh
ip_vs_wrr
ip_vs_rr
ip_vs
nf_conntrack

1.12 配置Linux內核(cilium必選)

cilium和其他的cni組件最大的不同在于其底層使用了ebpf技術,而該技術對于Linux的系統內核版本有較高的要求,完成的要求可以查看官網的詳細鏈接,這里我們著重看內核版本、內核參數這兩個部分。

Linux內核版本

默認情況下我們可以參考cilium官方給出的一個系統要求總結。因為我們是在k8s集群中部署(使用容器),因此只需要關注Linux內核版本和etcd版本即可。根據前面部署的經驗我們可以知道1.23.6版本的k8s默認使用的etcd版本是3.5.+,因此重點就來到了Linux內核版本這里。

Requirement Minimum Version In cilium container
Linux kernel >= 4.9.17 no
Key-Value store (etcd) >= 3.1.0 no
clang+LLVM >= 10.0 yes
iproute2 >= 5.9.0 yes

This requirement is only needed if you run cilium-agent natively. If you are using the Cilium container image cilium/cilium, clang+LLVM is included in the container image.

iproute2 is only needed if you run cilium-agent directly on the host machine. iproute2 is included in the cilium/cilium container image.

毫無疑問CentOS7內置的默認內核版本3.10.x版本的內核是無法滿足需求的,但是在升級內核之前,我們再看看其他的一些要求。

cilium官方還給出了一份列表描述了各項高級功能對內核版本的要求:

Cilium Feature Minimum Kernel Version
IPv4 fragment handling >= 4.10
Restrictions on unique prefix lengths for CIDR policy rules >= 4.11
IPsec Transparent Encryption in tunneling mode >= 4.19
WireGuard Transparent Encryption >= 5.6
Host-Reachable Services >= 4.19.57, >= 5.1.16, >= 5.2
Kubernetes Without kube-proxy >= 4.19.57, >= 5.1.16, >= 5.2
Bandwidth Manager >= 5.1
Local Redirect Policy (beta) >= 4.19.57, >= 5.1.16, >= 5.2
Full support for Session Affinity >= 5.7
BPF-based proxy redirection >= 5.7
BPF-based host routing >= 5.10
Socket-level LB bypass in pod netns >= 5.7
Egress Gateway (beta) >= 5.2
VXLAN Tunnel Endpoint (VTEP) Integration >= 5.2

可以看到如果需要滿足上面所有需求的話,需要內核版本高于5.10,本著學習測試研究作死的精神,反正都升級了,干脆就升級到新一些的版本吧。這里我們可以直接使用elrepo源來升級內核到較新的內核版本。

# 查看elrepo源中支持的內核版本
$ yum --disablerepo="*" --enablerepo="elrepo-kernel" list available
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
Available Packages
elrepo-release.noarch                                                                   7.0-5.el7.elrepo                                                           elrepo-kernel
kernel-lt.x86_64                                                                        5.4.192-1.el7.elrepo                                                       elrepo-kernel
kernel-lt-devel.x86_64                                                                  5.4.192-1.el7.elrepo                                                       elrepo-kernel
kernel-lt-doc.noarch                                                                    5.4.192-1.el7.elrepo                                                       elrepo-kernel
kernel-lt-headers.x86_64                                                                5.4.192-1.el7.elrepo                                                       elrepo-kernel
kernel-lt-tools.x86_64                                                                  5.4.192-1.el7.elrepo                                                       elrepo-kernel
kernel-lt-tools-libs.x86_64                                                             5.4.192-1.el7.elrepo                                                       elrepo-kernel
kernel-lt-tools-libs-devel.x86_64                                                       5.4.192-1.el7.elrepo                                                       elrepo-kernel
kernel-ml.x86_64                                                                        5.17.6-1.el7.elrepo                                                        elrepo-kernel
kernel-ml-devel.x86_64                                                                  5.17.6-1.el7.elrepo                                                        elrepo-kernel
kernel-ml-doc.noarch                                                                    5.17.6-1.el7.elrepo                                                        elrepo-kernel
kernel-ml-headers.x86_64                                                                5.17.6-1.el7.elrepo                                                        elrepo-kernel
kernel-ml-tools.x86_64                                                                  5.17.6-1.el7.elrepo                                                        elrepo-kernel
kernel-ml-tools-libs.x86_64                                                             5.17.6-1.el7.elrepo                                                        elrepo-kernel
kernel-ml-tools-libs-devel.x86_64                                                       5.17.6-1.el7.elrepo                                                        elrepo-kernel
perf.x86_64                                                                             5.17.6-1.el7.elrepo                                                        elrepo-kernel
python-perf.x86_64                                                                      5.17.6-1.el7.elrepo                                                        elrepo-kernel

# 看起來ml版本的內核比較滿足我們的需求,直接使用yum進行安裝
sudo yum --enablerepo=elrepo-kernel install kernel-ml -y
# 使用grubby工具查看系統中已經安裝的內核版本信息
sudo grubby --info=ALL
# 設置新安裝的5.17.6版本內核為默認內核版本,此處的index=0要和上面查看的內核版本信息一致
sudo grubby --set-default-index=0
# 查看默認內核是否修改成功
sudo grubby --default-kernel
# 重啟系統切換到新內核
init 6
# 重啟后檢查內核版本是否為新的5.17.6
uname -a

Linux內核參數

首先我們查看自己當前內核版本的參數,基本上可以分為ynm三個選項

  • y:yes,Build directly into the kernel. 表示該功能被編譯進內核中,默認啟用
  • n:no,Leave entirely out of the kernel. 表示該功能未被編譯進內核中,不啟用
  • m:module,Build as a module, to be loaded if needed. 表示該功能被編譯為模塊,按需啟用
# 查看當前使用的內核版本的編譯參數
cat /boot/config-$(uname -r)

cilium官方對各項功能所需要開啟的內核參數列舉如下:

In order for the eBPF feature to be enabled properly, the following kernel configuration options must be enabled. This is typically the case with distribution kernels. When an option can be built as a module or statically linked, either choice is valid.

為了正確啟用 eBPF 功能,必須啟用以下內核配置選項。這通常因內核版本情況而異。任何一個選項都可以構建為模塊或靜態鏈接,兩個選擇都是有效的。

我們暫時只看最基本的Base Requirements

CONFIG_BPF=y
CONFIG_BPF_SYSCALL=y
CONFIG_NET_CLS_BPF=y
CONFIG_BPF_JIT=y
CONFIG_NET_CLS_ACT=y
CONFIG_NET_SCH_INGRESS=y
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_USER_API_HASH=y
CONFIG_CGROUPS=y
CONFIG_CGROUP_BPF=y

對比我們使用的5.17.6-1.el7.elrepo.x86_64內核可以發現有兩個模塊是為m

$ egrep "^CONFIG_BPF=|^CONFIG_BPF_SYSCALL=|^CONFIG_NET_CLS_BPF=|^CONFIG_BPF_JIT=|^CONFIG_NET_CLS_ACT=|^CONFIG_NET_SCH_INGRESS=|^CONFIG_CRYPTO_SHA1=|^CONFIG_CRYPTO_USER_API_HASH=|^CONFIG_CGROUPS=|^CONFIG_CGROUP_BPF=" /boot/config-5.17.6-1.el7.elrepo.x86_64
CONFIG_BPF=y
CONFIG_BPF_SYSCALL=y
CONFIG_BPF_JIT=y
CONFIG_CGROUPS=y
CONFIG_CGROUP_BPF=y
CONFIG_NET_SCH_INGRESS=m
CONFIG_NET_CLS_BPF=m
CONFIG_NET_CLS_ACT=y
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_USER_API_HASH=y

缺少的這兩個模塊我們可以在/usr/lib/modules/$(uname -r)目錄下面找到它們:

$ realpath ./kernel/net/sched/sch_ingress.ko
/usr/lib/modules/5.17.6-1.el7.elrepo.x86_64/kernel/net/sched/sch_ingress.ko
$ realpath ./kernel/net/sched/cls_bpf.ko
/usr/lib/modules/5.17.6-1.el7.elrepo.x86_64/kernel/net/sched/cls_bpf.ko

確認相關內核模塊存在我們直接加載內核即可:

# 直接使用modprobe命令加載
$ modprobe cls_bpf
$ modprobe sch_ingress
$ lsmod | egrep "cls_bpf|sch_ingress"
sch_ingress            16384  0
cls_bpf                24576  0

# 配置開機自動加載cilium所需相關模塊
cat <<EOF | sudo tee /etc/modules-load.d/cilium-base-requirements.conf
cls_bpf
sch_ingress
EOF

其他cilium高級功能所需要的內核功能也類似,這里不做贅述。

2、安裝container runtime

2.1 安裝docker

詳細的官方文檔可以參考這里,由于在剛發布的1.24版本中移除了docker-shim,因此安裝的版本≥1.24的時候需要注意容器運行時的選擇。這里我們安裝的版本低于1.24,因此我們繼續使用docker。

docker的具體安裝可以參考我之前寫的這篇文章,這里不做贅述。

# 安裝必要的依賴組件并且導入docker官方提供的yum源
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
sudo yum-config-manager --add-repo  https://download.docker.com/linux/centos/docker-ce.repo

# 我們直接安裝最新版本的docker
yum install docker-ce docker-ce-cli containerd.io

2.2 配置cgroup drivers

CentOS7使用的是systemd來初始化系統并管理進程,初始化進程會生成并使用一個 root 控制組 (cgroup), 并充當 cgroup 管理器。 Systemdcgroup 集成緊密,并將為每個 systemd 單元分配一個 cgroup。 我們也可以配置容器運行時kubelet 使用 cgroupfs。 連同 systemd 一起使用 cgroupfs 意味著將有兩個不同的 cgroup 管理器。而當一個系統中同時存在cgroupfs和systemd兩者時,容易變得不穩定,因此最好更改設置,令容器運行時和 kubelet 使用 systemd 作為 cgroup 驅動,以此使系統更為穩定。 對于 Docker, 需要設置 native.cgroupdriver=systemd 參數。

參考官方的說明文檔:

https://kubernetes.io/docs/setup/production-environment/container-runtimes/#cgroup-drivers

參考配置說明文檔

https://kubernetes.io/zh/docs/setup/production-environment/container-runtimes/#docker

sudo mkdir /etc/docker
cat <<EOF | sudo tee /etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
EOF

sudo systemctl enable docker
sudo systemctl daemon-reload
sudo systemctl restart docker


# 最后檢查一下Cgroup Driver是否為systemd
$ docker info | grep systemd
 Cgroup Driver: systemd

2.3 關于kubelet的cgroup driver

k8s官方有詳細的文檔介紹了如何設置kubelet的cgroup driver,需要特別注意的是,在1.22版本開始,如果沒有手動設置kubelet的cgroup driver,那么默認會設置為systemd

Note: In v1.22, if the user is not setting the cgroupDriver field under KubeletConfiguration, kubeadm will default it to systemd.

一個比較簡單的指定kubelet的cgroup driver的方法就是在kubeadm-config.yaml加入cgroupDriver字段

# kubeadm-config.yaml
kind: ClusterConfiguration
apiVersion: kubeadm.k8s.io/v1beta3
kubernetesVersion: v1.21.0
---
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
cgroupDriver: systemd

我們可以直接查看configmaps來查看初始化之后集群的kubeadm-config配置。

$ kubectl describe configmaps kubeadm-config -n kube-system
Name:         kubeadm-config
Namespace:    kube-system
Labels:       <none>
Annotations:  <none>

Data
====
ClusterConfiguration:
----
apiServer:
  extraArgs:
    authorization-mode: Node,RBAC
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: v1.23.6
networking:
  dnsDomain: cali-cluster.tclocal
  serviceSubnet: 10.88.0.0/18
scheduler: {}


BinaryData
====

Events:  <none>

當然因為我們需要安裝的版本高于1.22.0并且使用的就是systemd,因此可以不用再重復配置。

3、安裝kube三件套

對應的官方文檔可以參考這里

https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#installing-kubeadm-kubelet-and-kubectl

kube三件套就是kubeadmkubeletkubectl,三者的具體功能和作用如下:

  • kubeadm:用來初始化集群的指令。
  • kubelet:在集群中的每個節點上用來啟動 Pod 和容器等。
  • kubectl:用來與集群通信的命令行工具。

需要注意的是:

  • kubeadm不會幫助我們管理kubeletkubectl,其他兩者也是一樣的,也就是說這三者是相互獨立的,并不存在誰管理誰的情況;
  • kubelet的版本必須小于等于API-server的版本,否則容易出現兼容性的問題;
  • kubectl并不是集群中的每個節點都需要安裝,也并不是一定要安裝在集群中的節點,可以單獨安裝在自己本地的機器環境上面,然后配合kubeconfig文件即可使用kubectl命令來遠程管理對應的k8s集群;

CentOS7的安裝比較簡單,我們直接使用官方提供的yum源即可。需要注意的是這里需要設置selinux的狀態,但是前面我們已經關閉了selinux,因此這里略過這步。

# 直接導入谷歌官方的yum源
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kubelet kubeadm kubectl
EOF

# 當然如果連不上谷歌的源,可以考慮使用國內的阿里鏡像源
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF


# 接下來直接安裝三件套即可
sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes

# 如果網絡環境不好出現gpgcheck驗證失敗導致無法正常讀取yum源,可以考慮關閉該yum源的repo_gpgcheck
sed -i 's/repo_gpgcheck=1/repo_gpgcheck=0/g' /etc/yum.repos.d/kubernetes.repo
# 或者在安裝的時候禁用gpgcheck
sudo yum install -y kubelet kubeadm kubectl --nogpgcheck --disableexcludes=kubernetes



# 如果想要安裝特定版本,可以使用這個命令查看相關版本的信息
sudo yum list --nogpgcheck kubelet kubeadm kubectl --showduplicates --disableexcludes=kubernetes
# 這里我們為了保留使用docker-shim,因此我們按照1.24.0版本的前一個版本1.23.6
sudo yum install -y kubelet-1.23.6-0 kubeadm-1.23.6-0 kubectl-1.23.6-0 --nogpgcheck --disableexcludes=kubernetes

# 安裝完成后配置開機自啟kubelet
sudo systemctl enable --now kubelet

4、初始化集群

4.1 編寫配置文件

在集群中所有節點都執行完上面的三點操作之后,我們就可以開始創建k8s集群了。因為我們這次不涉及高可用部署,因此初始化的時候直接在我們的目標master節點上面操作即可。

# 我們先使用kubeadm命令查看一下主要的幾個鏡像版本
# 因為我們此前指定安裝了舊的1.23.6版本,這里的apiserver鏡像版本也會隨之回滾
$ kubeadm config images list
I0509 12:06:03.036544    3593 version.go:255] remote version is much newer: v1.24.0; falling back to: stable-1.23
k8s.gcr.io/kube-apiserver:v1.23.6
k8s.gcr.io/kube-controller-manager:v1.23.6
k8s.gcr.io/kube-scheduler:v1.23.6
k8s.gcr.io/kube-proxy:v1.23.6
k8s.gcr.io/pause:3.6
k8s.gcr.io/etcd:3.5.1-0
k8s.gcr.io/coredns/coredns:v1.8.6

# 為了方便編輯和管理,我們還是把初始化參數導出成配置文件
$ kubeadm config print init-defaults > kubeadm-cilium.conf

  • 考慮到大多數情況下國內的網絡無法使用谷歌的k8s.gcr.io鏡像源,我們可以直接在配置文件中修改imageRepository參數為阿里的鏡像源
  • kubernetesVersion字段用來指定我們要安裝的k8s版本
  • localAPIEndpoint參數需要修改為我們的master節點的IP和端口,初始化之后的k8s集群的apiserver地址就是這個
  • podSubnetserviceSubnetdnsDomain兩個參數默認情況下可以不用修改,這里我按照自己的需求進行了變更
  • nodeRegistration里面的name參數修改為對應master節點的hostname
  • 新增配置塊使用ipvs,具體可以參考官方文檔
apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 10.31.188.1
  bindPort: 6443
nodeRegistration:
  criSocket: /var/run/dockershim.sock
  imagePullPolicy: IfNotPresent
  name: tiny-cilium-master-188-1.k8s.tcinternal
  taints: null
---
apiServer:
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: 1.23.6
networking:
  dnsDomain: cili-cluster.tclocal
  serviceSubnet: 10.188.0.0/18
  podSubnet: 10.188.64.0/18
scheduler: {}
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs

4.2 初始化集群

此時我們再查看對應的配置文件中的鏡像版本,就會發現已經變成了對應阿里云鏡像源的版本

# 查看一下對應的鏡像版本,確定配置文件是否生效
$ kubeadm config images list --config kubeadm-cilium.conf
registry.aliyuncs.com/google_containers/kube-apiserver:v1.23.6
registry.aliyuncs.com/google_containers/kube-controller-manager:v1.23.6
registry.aliyuncs.com/google_containers/kube-scheduler:v1.23.6
registry.aliyuncs.com/google_containers/kube-proxy:v1.23.6
registry.aliyuncs.com/google_containers/pause:3.6
registry.aliyuncs.com/google_containers/etcd:3.5.1-0
registry.aliyuncs.com/google_containers/coredns:v1.8.6

# 確認沒問題之后我們直接拉取鏡像
$ kubeadm config images pull --config kubeadm-cilium.conf
[config/images] Pulled registry.aliyuncs.com/google_containers/kube-apiserver:v1.23.6
[config/images] Pulled registry.aliyuncs.com/google_containers/kube-controller-manager:v1.23.6
[config/images] Pulled registry.aliyuncs.com/google_containers/kube-scheduler:v1.23.6
[config/images] Pulled registry.aliyuncs.com/google_containers/kube-proxy:v1.23.6
[config/images] Pulled registry.aliyuncs.com/google_containers/pause:3.6
[config/images] Pulled registry.aliyuncs.com/google_containers/etcd:3.5.1-0
[config/images] Pulled registry.aliyuncs.com/google_containers/coredns:v1.8.6

# 初始化
$ kubeadm init --config kubeadm-cilium.conf
[init] Using Kubernetes version: v1.23.6
[preflight] Running pre-flight checks
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
...此處略去一堆輸出...

當我們看到下面這個輸出結果的時候,我們的集群就算是初始化成功了。

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 10.31.188.1:6443 --token abcdef.0123456789abcdef \
        --discovery-token-ca-cert-hash sha256:fbe33f0dbda199b487a78948a4c693660d742d0dfc270bad2963a035b4971ade

4.3 配置kubeconfig

剛初始化成功之后,我們還沒辦法馬上查看k8s集群信息,需要配置kubeconfig相關參數才能正常使用kubectl連接apiserver讀取集群信息。

# 對于非root用戶,可以這樣操作
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# 如果是root用戶,可以直接導入環境變量
export KUBECONFIG=/etc/kubernetes/admin.conf

# 添加kubectl的自動補全功能
echo "source <(kubectl completion bash)" >> ~/.bashrc

前面我們提到過kubectl不一定要安裝在集群內,實際上只要是任何一臺能連接到apiserver的機器上面都可以安裝kubectl并且根據步驟配置kubeconfig,就可以使用kubectl命令行來管理對應的k8s集群。

配置完成后,我們再執行相關命令就可以查看集群的信息了。

$ kubectl cluster-info
Kubernetes control plane is running at https://10.31.188.1:6443
CoreDNS is running at https://10.31.188.1:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.


$ kubectl get nodes -o wide
NAME                                      STATUS     ROLES                  AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION               CONTAINER-RUNTIME
tiny-cilium-master-188-1.k8s.tcinternal   NotReady   control-plane,master   84s   v1.23.6   10.31.188.1   <none>        CentOS Linux 7 (Core)   5.17.6-1.el7.elrepo.x86_64   docker://20.10.14

$ kubectl get pods -A -o wide
NAMESPACE     NAME                                                              READY   STATUS    RESTARTS   AGE   IP            NODE                                      NOMINATED NODE   READINESS GATES
kube-system   coredns-6d8c4cb4d-285cl                                           0/1     Pending   0          78s   <none>        <none>                                    <none>           <none>
kube-system   coredns-6d8c4cb4d-6zntv                                           0/1     Pending   0          78s   <none>        <none>                                    <none>           <none>
kube-system   etcd-tiny-cilium-master-188-1.k8s.tcinternal                      1/1     Running   0          90s   10.31.188.1   tiny-cilium-master-188-1.k8s.tcinternal   <none>           <none>
kube-system   kube-apiserver-tiny-cilium-master-188-1.k8s.tcinternal            1/1     Running   0          92s   10.31.188.1   tiny-cilium-master-188-1.k8s.tcinternal   <none>           <none>
kube-system   kube-controller-manager-tiny-cilium-master-188-1.k8s.tcinternal   1/1     Running   0          90s   10.31.188.1   tiny-cilium-master-188-1.k8s.tcinternal   <none>           <none>
kube-system   kube-proxy-m7q5n                                                  1/1     Running   0          78s   10.31.188.1   tiny-cilium-master-188-1.k8s.tcinternal   <none>           <none>
kube-system   kube-scheduler-tiny-cilium-master-188-1.k8s.tcinternal            1/1     Running   0          91s   10.31.188.1   tiny-cilium-master-188-1.k8s.tcinternal   <none>           <none>

4.4 添加worker節點

這時候我們還需要繼續添加剩下的兩個節點作為worker節點運行負載,直接在剩下的節點上面運行集群初始化成功時輸出的命令就可以成功加入集群。

$ kubeadm join 10.31.188.1:6443 --token abcdef.0123456789abcdef \
>         --discovery-token-ca-cert-hash sha256:fbe33f0dbda199b487a78948a4c693660d742d0dfc270bad2963a035b4971ade
[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...

This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the control-plane to see this node join the cluster.

如果不小心沒保存初始化成功的輸出信息也沒有關系,我們可以使用kubectl工具查看或者生成token

# 查看現有的token列表
$ kubeadm token list
TOKEN                     TTL         EXPIRES                USAGES                   DESCRIPTION                                                EXTRA GROUPS
abcdef.0123456789abcdef   23h         2022-05-10T05:46:11Z   authentication,signing   <none>                                                     system:bootstrappers:kubeadm:default-node-token

# 如果token已經失效,那就再創建一個新的token
$ kubeadm token create
xd468t.co8ye3su70bojo2k
$ kubeadm token list
TOKEN                     TTL         EXPIRES                USAGES                   DESCRIPTION                                                EXTRA GROUPS
abcdef.0123456789abcdef   23h         2022-05-10T05:46:11Z   authentication,signing   <none>                                                     system:bootstrappers:kubeadm:default-node-token
xd468t.co8ye3su70bojo2k   23h         2022-05-10T05:58:40Z   authentication,signing   <none>                                                     system:bootstrappers:kubeadm:default-node-token

# 如果找不到--discovery-token-ca-cert-hash參數,則可以在master節點上使用openssl工具來獲取
$ openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
0d68339d3e5a045dc093470321f8f6334223e97f360542477c4f480bda34d72a

添加完成之后我們再查看集群的節點可以發現這時候已經多了兩個node,但是此時節點的狀態還是NotReady,接下來就需要部署CNI了。

$ kubectl get nodes
NAME                                       STATUS     ROLES                  AGE     VERSION
tiny-cilium-master-188-1.k8s.tcinternal    NotReady   control-plane,master   2m47s   v1.23.6
tiny-cilium-worker-188-11.k8s.tcinternal   NotReady   <none>                 41s     v1.23.6
tiny-cilium-worker-188-12.k8s.tcinternal   NotReady   <none>                 30s     v1.23.6

5、安裝CNI

5.1 安裝cilium

快速安裝的教程可以參考官網文檔,基本的安裝思路就是先下載cilium官方的cli工具,然后使用cli工具進行安裝。

這種安裝方式的優勢就是簡單快捷,缺點就是缺少自定義參數配置的功能,只能使用官方原先設置的默認參數,比較適合快速初始化搭建可用環境用來學習和測試。

# cilium的cli工具是一個二進制的可執行文件
$ curl -L --remote-name-all https://github.com/cilium/cilium-cli/releases/latest/download/cilium-linux-amd64.tar.gz{,.sha256sum}
$ sha256sum --check cilium-linux-amd64.tar.gz.sha256sum
cilium-linux-amd64.tar.gz: OK
$ sudo tar xzvfC cilium-linux-amd64.tar.gz /usr/local/bin
cilium

# 使用該命令即可完成cilium的安裝
$ cilium install
??  using Cilium version "v1.11.3"
?? Auto-detected cluster name: kubernetes
?? Auto-detected IPAM mode: cluster-pool
??  helm template --namespace kube-system cilium cilium/cilium --version 1.11.3 --set cluster.id=0,cluster.name=kubernetes,encryption.nodeEncryption=false,ipam.mode=cluster-pool,kubeProxyReplacement=disabled,operator.replicas=1,serviceAccounts.cilium.name=cilium,serviceAccounts.operator.name=cilium-operator
??  Storing helm values file in kube-system/cilium-cli-helm-values Secret
?? Created CA in secret cilium-ca
?? Generating certificates for Hubble...
?? Creating Service accounts...
?? Creating Cluster roles...
?? Creating ConfigMap for Cilium version 1.11.3...
?? Creating Agent DaemonSet...
level=warning msg="spec.template.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[1].matchExpressions[0].key: beta.kubernetes.io/os is deprecated since v1.14; use \"kubernetes.io/os\" instead" subsys=klog
level=warning msg="spec.template.metadata.annotations[scheduler.alpha.kubernetes.io/critical-pod]: non-functional in v1.16+; use the \"priorityClassName\" field instead" subsys=klog
?? Creating Operator Deployment...
? Waiting for Cilium to be installed and ready...
? Cilium was successfully installed! Run 'cilium status' to view installation health

# 查看cilium的狀態
$ cilium status
    /ˉˉ\
 /ˉˉ\__/ˉˉ\    Cilium:         OK
 \__/ˉˉ\__/    Operator:       OK
 /ˉˉ\__/ˉˉ\    Hubble:         disabled
 \__/ˉˉ\__/    ClusterMesh:    disabled
    \__/

DaemonSet         cilium             Desired: 3, Ready: 3/3, Available: 3/3
Deployment        cilium-operator    Desired: 1, Ready: 1/1, Available: 1/1
Containers:       cilium-operator    Running: 1
                  cilium             Running: 3
Cluster Pods:     2/2 managed by Cilium
Image versions    cilium             quay.io/cilium/cilium:v1.11.3@sha256:cb6aac121e348abd61a692c435a90a6e2ad3f25baa9915346be7b333de8a767f: 3
                  cilium-operator    quay.io/cilium/operator-generic:v1.11.3@sha256:5b81db7a32cb7e2d00bb3cf332277ec2b3be239d9e94a8d979915f4e6648c787: 1

5.2 配置hubble

# 我們先使用cilium-cli工具在k8s集群中部署hubble,只需要下面一條命令即可
$ cilium hubble enable
?? Found CA in secret cilium-ca
??  helm template --namespace kube-system cilium cilium/cilium --version 1.11.3 --set cluster.id=0,cluster.name=kubernetes,encryption.nodeEncryption=false,hubble.enabled=true,hubble.relay.enabled=true,hubble.tls.ca.cert=LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNGRENDQWJxZ0F3SUJBZ0lVSDRQcit1UU0xSXZtdWQvVlV3YWlycGllSEZBd0NnWUlLb1pJemowRUF3SXcKYURFTE1Ba0dBMVVFQmhNQ1ZWTXhGakFVQmdOVkJBZ1REVk5oYmlCR2NtRnVZMmx6WTI4eEN6QUpCZ05WQkFjVApBa05CTVE4d0RRWURWUVFLRXdaRGFXeHBkVzB4RHpBTkJnTlZCQXNUQmtOcGJHbDFiVEVTTUJBR0ExVUVBeE1KClEybHNhWFZ0SUVOQk1CNFhEVEl5TURVd09UQTVNREF3TUZvWERUSTNNRFV3T0RBNU1EQXdNRm93YURFTE1Ba0cKQTFVRUJoTUNWVk14RmpBVUJnTlZCQWdURFZOaGJpQkdjbUZ1WTJselkyOHhDekFKQmdOVkJBY1RBa05CTVE4dwpEUVlEVlFRS0V3WkRhV3hwZFcweER6QU5CZ05WQkFzVEJrTnBiR2wxYlRFU01CQUdBMVVFQXhNSlEybHNhWFZ0CklFTkJNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUU3Z21EQ05WOERseEIxS3VYYzhEdndCeUoKWUxuSENZNjVDWUhBb3ZBY3FUM3drcitLVVNwelcyVjN0QW9IaFdZV0UyQ2lUNjNIOXZLV1ZRY3pHeXp1T0tOQwpNRUF3RGdZRFZSMFBBUUgvQkFRREFnRUdNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdIUVlEVlIwT0JCWUVGQmMrClNDb3F1Y0JBc09sdDBWaEVCbkwyYjEyNE1Bb0dDQ3FHU000OUJBTUNBMGdBTUVVQ0lRRDJsNWVqaDVLVTkySysKSHJJUXIweUwrL05pZ3NSUHRBblA5T3lDcHExbFJBSWdYeGY5a2t5N2xYU0pOYmpkREFjbnBrNlJFTFp2eEkzbQpKaG9JRkRlbER0dz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=,hubble.tls.ca.key=[--- REDACTED WHEN PRINTING TO TERMINAL (USE --redact-helm-certificate-keys=false TO PRINT) ---],ipam.mode=cluster-pool,kubeProxyReplacement=disabled,operator.replicas=1,serviceAccounts.cilium.name=cilium,serviceAccounts.operator.name=cilium-operator
? Patching ConfigMap cilium-config to enable Hubble...
?? Creating ConfigMap for Cilium version 1.11.3...
??  Restarted Cilium pods
? Waiting for Cilium to become ready before deploying other Hubble component(s)...
? Generating certificates...
?? Generating certificates for Relay...
? Deploying Relay...
? Waiting for Hubble to be installed...
??  Storing helm values file in kube-system/cilium-cli-helm-values Secret
? Hubble was successfully enabled!


# 安裝hubble-cli工具,安裝邏輯和cilium-cli的邏輯相似
$ export HUBBLE_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/hubble/master/stable.txt)
$ curl -L --remote-name-all https://github.com/cilium/hubble/releases/download/$HUBBLE_VERSION/hubble-linux-amd64.tar.gz{,.sha256sum}
$ sha256sum --check hubble-linux-amd64.tar.gz.sha256sum
hubble-linux-amd64.tar.gz: OK
$ sudo tar xzvfC hubble-linux-amd64.tar.gz /usr/local/bin
hubble

# 首先我們要開啟hubble的api,使用cilium-cli開啟轉發
$ cilium hubble port-forward&
[1] 15512
$ kubectl get svc -n kube-system
NAME           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                  AGE
hubble-relay   ClusterIP   10.188.55.197   <none>        80/TCP                   16h
hubble-ui      ClusterIP   10.188.17.78    <none>        80/TCP                   16h
kube-dns       ClusterIP   10.188.0.10     <none>        53/UDP,53/TCP,9153/TCP   17h
$ netstat -ntulp | grep 4245
tcp        0      0 0.0.0.0:4245            0.0.0.0:*               LISTEN      15527/kubectl
tcp6       0      0 :::4245                 :::*                    LISTEN      15527/kubectl

# 實際上執行的操作等同于下面這個命令
# kubectl port-forward -n kube-system svc/hubble-relay --address 0.0.0.0 --address :: 4245:80


# 測試和hubble-api的連通性
$ hubble status
Healthcheck (via localhost:4245): Ok
Current/Max Flows: 12,285/12,285 (100.00%)
Flows/s: 28.58
Connected Nodes: 3/3

# 使用hubble命令查看數據的轉發情況
$ hubble observe
Handling connection for 4245
May  9 09:33:25.861: 10.0.1.47:44484 -> cilium-test/echo-same-node-5767b7b99d-xhzpb:8080 to-endpoint FORWARDED (TCP Flags: ACK, PSH)
May  9 09:33:25.863: 10.0.1.47:44484 <- cilium-test/echo-same-node-5767b7b99d-xhzpb:8080 to-stack FORWARDED (TCP Flags: ACK, PSH)
May  9 09:33:25.864: 10.0.1.47:44484 -> cilium-test/echo-same-node-5767b7b99d-xhzpb:8080 to-endpoint FORWARDED (TCP Flags: ACK, FIN)
...此處略去一堆輸出...

# 開啟hubble ui組件
$ cilium hubble enable --ui
?? Found CA in secret cilium-ca
??  helm template --namespace kube-system cilium cilium/cilium --version 1.11.3 --set cluster.id=0,cluster.name=kubernetes,encryption.nodeEncryption=false,hubble.enabled=true,hubble.relay.enabled=true,hubble.tls.ca.cert=LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNGRENDQWJxZ0F3SUJBZ0lVSDRQcit1UU0xSXZtdWQvVlV3YWlycGllSEZBd0NnWUlLb1pJemowRUF3SXcKYURFTE1Ba0dBMVVFQmhNQ1ZWTXhGakFVQmdOVkJBZ1REVk5oYmlCR2NtRnVZMmx6WTI4eEN6QUpCZ05WQkFjVApBa05CTVE4d0RRWURWUVFLRXdaRGFXeHBkVzB4RHpBTkJnTlZCQXNUQmtOcGJHbDFiVEVTTUJBR0ExVUVBeE1KClEybHNhWFZ0SUVOQk1CNFhEVEl5TURVd09UQTVNREF3TUZvWERUSTNNRFV3T0RBNU1EQXdNRm93YURFTE1Ba0cKQTFVRUJoTUNWVk14RmpBVUJnTlZCQWdURFZOaGJpQkdjbUZ1WTJselkyOHhDekFKQmdOVkJBY1RBa05CTVE4dwpEUVlEVlFRS0V3WkRhV3hwZFcweER6QU5CZ05WQkFzVEJrTnBiR2wxYlRFU01CQUdBMVVFQXhNSlEybHNhWFZ0CklFTkJNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUU3Z21EQ05WOERseEIxS3VYYzhEdndCeUoKWUxuSENZNjVDWUhBb3ZBY3FUM3drcitLVVNwelcyVjN0QW9IaFdZV0UyQ2lUNjNIOXZLV1ZRY3pHeXp1T0tOQwpNRUF3RGdZRFZSMFBBUUgvQkFRREFnRUdNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdIUVlEVlIwT0JCWUVGQmMrClNDb3F1Y0JBc09sdDBWaEVCbkwyYjEyNE1Bb0dDQ3FHU000OUJBTUNBMGdBTUVVQ0lRRDJsNWVqaDVLVTkySysKSHJJUXIweUwrL05pZ3NSUHRBblA5T3lDcHExbFJBSWdYeGY5a2t5N2xYU0pOYmpkREFjbnBrNlJFTFp2eEkzbQpKaG9JRkRlbER0dz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=,hubble.tls.ca.key=[--- REDACTED WHEN PRINTING TO TERMINAL (USE --redact-helm-certificate-keys=false TO PRINT) ---],hubble.ui.enabled=true,hubble.ui.securityContext.enabled=false,ipam.mode=cluster-pool,kubeProxyReplacement=disabled,operator.replicas=1,serviceAccounts.cilium.name=cilium,serviceAccounts.operator.name=cilium-operator
? Patching ConfigMap cilium-config to enable Hubble...
?? Creating ConfigMap for Cilium version 1.11.3...
??  Restarted Cilium pods
? Waiting for Cilium to become ready before deploying other Hubble component(s)...
? Relay is already deployed
? Deploying Hubble UI and Hubble UI Backend...
? Waiting for Hubble to be installed...
??  Storing helm values file in kube-system/cilium-cli-helm-values Secret
? Hubble was successfully enabled!

# 實際上這時候我們再查看k8s集群的狀態可以看到部署了一個名為hubble-ui的deployment
$ kubectl get deployment -n kube-system | grep hubble
hubble-relay      1/1     1            1           17h
hubble-ui         1/1     1            1           17h
$ kubectl get svc -n kube-system | grep hubble
hubble-relay   ClusterIP   10.188.55.197   <none>        80/TCP                   17h
hubble-ui      ClusterIP   10.188.17.78    <none>        80/TCP                   17h

# 將hubble-ui這個服務的80端口暴露到宿主機上面的12000端口上面
$ cilium hubble ui&
[2] 5809
??  Opening "http://localhost:12000" in your browser...
# 實際上執行的操作等同于下面這個命令
# kubectl port-forward -n kube-system svc/hubble-ui --address 0.0.0.0 --address :: 12000:80

訪問k8s宿主機節點的IP+端口就可以看到hubble-ui的界面了

[圖片上傳失敗...(image-e65d6a-1653405092639)]

最后所有的相關服務都部署完成之后,我們再檢查一下整個cilium的狀態

$ cilium status
    /ˉˉ\
 /ˉˉ\__/ˉˉ\    Cilium:         OK
 \__/ˉˉ\__/    Operator:       OK
 /ˉˉ\__/ˉˉ\    Hubble:         OK
 \__/ˉˉ\__/    ClusterMesh:    disabled
    \__/

Deployment        cilium-operator    Desired: 1, Ready: 1/1, Available: 1/1
Deployment        hubble-relay       Desired: 1, Ready: 1/1, Available: 1/1
Deployment        hubble-ui          Desired: 1, Ready: 1/1, Available: 1/1
DaemonSet         cilium             Desired: 3, Ready: 3/3, Available: 3/3
Containers:       cilium             Running: 3
                  cilium-operator    Running: 1
                  hubble-relay       Running: 1
                  hubble-ui          Running: 1
Cluster Pods:     8/8 managed by Cilium
Image versions    cilium             quay.io/cilium/cilium:v1.11.3@sha256:cb6aac121e348abd61a692c435a90a6e2ad3f25baa9915346be7b333de8a767f: 3
                  cilium-operator    quay.io/cilium/operator-generic:v1.11.3@sha256:5b81db7a32cb7e2d00bb3cf332277ec2b3be239d9e94a8d979915f4e6648c787: 1
                  hubble-relay       quay.io/cilium/hubble-relay:v1.11.3@sha256:7256ec111259a79b4f0e0f80ba4256ea23bd472e1fc3f0865975c2ed113ccb97: 1
                  hubble-ui          quay.io/cilium/hubble-ui:v0.8.5@sha256:4eaca1ec1741043cfba6066a165b3bf251590cf4ac66371c4f63fbed2224ebb4: 1
                  hubble-ui          quay.io/cilium/hubble-ui-backend:v0.8.5@sha256:2bce50cf6c32719d072706f7ceccad654bfa907b2745a496da99610776fe31ed: 1
                  hubble-ui          docker.io/envoyproxy/envoy:v1.18.4@sha256:e5c2bb2870d0e59ce917a5100311813b4ede96ce4eb0c6bfa879e3fbe3e83935: 1

6、部署測試用例

集群部署完成之后我們在k8s集群中部署一個nginx測試一下是否能夠正常工作。首先我們創建一個名為nginx-quic的命名空間(namespace),然后在這個命名空間內創建一個名為nginx-quic-deploymentdeployment用來部署pod,最后再創建一個service用來暴露服務,這里我們先使用nodeport的方式暴露端口方便測試。

$ cat nginx-quic.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: nginx-quic

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-quic-deployment
  namespace: nginx-quic
spec:
  selector:
    matchLabels:
      app: nginx-quic
  replicas: 4
  template:
    metadata:
      labels:
        app: nginx-quic
    spec:
      containers:
      - name: nginx-quic
        image: tinychen777/nginx-quic:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80

---

apiVersion: v1
kind: Service
metadata:
  name: nginx-quic-service
  namespace: nginx-quic
spec:
  externalTrafficPolicy: Cluster
  selector:
    app: nginx-quic
  ports:
  - protocol: TCP
    port: 8080 # match for service access port
    targetPort: 80 # match for pod access port
    nodePort: 30088 # match for external access port
  type: NodePort

部署完成后我們直接查看狀態

# 直接部署
$ kubectl apply -f nginx-quic.yaml
namespace/nginx-quic created
deployment.apps/nginx-quic-deployment created
service/nginx-quic-service created

# 查看deployment的運行狀態
$ kubectl get deployment -o wide -n nginx-quic
NAME                    READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES                          SELECTOR
nginx-quic-deployment   4/4     4            4           17h   nginx-quic   tinychen777/nginx-quic:latest   app=nginx-quic

# 查看service的運行狀態
$ kubectl get service -o wide -n nginx-quic
NAME                 TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE   SELECTOR
nginx-quic-service   NodePort   10.188.0.200   <none>        8080:30088/TCP   17h   app=nginx-quic

# 查看pod的運行狀態
$ kubectl get pods -o wide -n nginx-quic
NAME                                     READY   STATUS    RESTARTS      AGE   IP           NODE                                       NOMINATED NODE   READINESS GATES
nginx-quic-deployment-696d959797-26dzh   1/1     Running   1 (17h ago)   17h   10.0.2.58    tiny-cilium-worker-188-12.k8s.tcinternal   <none>           <none>
nginx-quic-deployment-696d959797-kw6bn   1/1     Running   1 (17h ago)   17h   10.0.2.207   tiny-cilium-worker-188-12.k8s.tcinternal   <none>           <none>
nginx-quic-deployment-696d959797-mdw99   1/1     Running   1 (17h ago)   17h   10.0.1.247   tiny-cilium-worker-188-11.k8s.tcinternal   <none>           <none>
nginx-quic-deployment-696d959797-x42zn   1/1     Running   1 (17h ago)   17h   10.0.1.60    tiny-cilium-worker-188-11.k8s.tcinternal   <none>           <none>

# 查看IPVS規則
$ ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  172.17.0.1:30088 rr
  -> 10.0.1.60:80                 Masq    1      0          0
  -> 10.0.1.247:80                Masq    1      0          0
  -> 10.0.2.58:80                 Masq    1      0          0
  -> 10.0.2.207:80                Masq    1      0          0
TCP  10.0.0.226:30088 rr
  -> 10.0.1.60:80                 Masq    1      0          0
  -> 10.0.1.247:80                Masq    1      0          0
  -> 10.0.2.58:80                 Masq    1      0          0
  -> 10.0.2.207:80                Masq    1      0          0
TCP  10.31.188.1:30088 rr
  -> 10.0.1.60:80                 Masq    1      0          0
  -> 10.0.1.247:80                Masq    1      0          0
  -> 10.0.2.58:80                 Masq    1      0          0
  -> 10.0.2.207:80                Masq    1      0          0
TCP  10.188.0.200:8080 rr
  -> 10.0.1.60:80                 Masq    1      0          0
  -> 10.0.1.247:80                Masq    1      0          0
  -> 10.0.2.58:80                 Masq    1      0          0
  -> 10.0.2.207:80                Masq    1      0          0

最后我們進行測試,這個nginx-quic的鏡像默認情況下會返回在nginx容器中獲得的用戶請求的IP和端口

# 首先我們在集群內進行測試
# 直接訪問pod
$ curl 10.0.2.58:80
10.0.0.226:52312
# 直接訪問service的ClusterIP,這時請求會被轉發到pod中
$ curl 10.188.0.200:8080
10.0.0.226:36228
# 直接訪問nodeport,這時請求會被轉發到pod中,不會經過ClusterIP
# 此時實際返回的IP要取決于被轉發到的后端pod是否在當前的k8s節點上
$ curl 10.31.188.1:30088
10.0.0.226:38034
$ curl 10.31.188.11:30088
10.31.188.11:24371
$ curl 10.31.188.12:30088
10.31.188.12:56919
$ curl 10.31.188.12:30088
10.0.2.151:49222

# 接著我們在集群外進行測試
# 直接訪問三個節點的nodeport,這時請求會被轉發到pod中,不會經過ClusterIP
# 此時實際返回的IP要取決于被轉發到的后端pod是否在當前的k8s節點上
$ curl 10.31.188.11:30088
10.0.1.47:6318
$ curl 10.31.188.11:30088
10.31.188.11:63944
$ curl 10.31.188.12:30088
10.31.188.12:53882
$ curl 10.31.188.12:30088
10.0.2.151:6366
$ curl 10.31.188.12:30088
10.0.2.151:6368
$ curl 10.31.188.12:30088
10.31.188.12:48174
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,646評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,595評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,560評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,035評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,814評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,224評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,301評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,444評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,988評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,804評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,998評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,544評論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,237評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,665評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,927評論 1 287
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,706評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,993評論 2 374

推薦閱讀更多精彩內容