k8s-adm快速部署生产案例
操作系统Ubuntu2404
机器规划
|
IP |
主机名 |
配置 |
|
192.168.139.161 |
k8s-master01 |
2c/4g |
|
192.168.139.162 |
k8s-node01 |
2c/4g |
前期环境准备
禁用Swap设备
- 所有机器都要配置
~# sed -i 's/^\/swap.*$/#&/g' /etc/fstab
`列出swap设备`
~# systemctl --type swap
...
UNIT LOAD ACTIVE SUB DESCRIPTION
swap.img.swap loaded active active /swap.img
...
`关闭swap设备`
~# systemctl mask swap.img.swap
~# swapoff -a
~# modprobe br_netfilter
~# echo "br_netfilter" | sudo tee /etc/modules-load.d/br_netfilter.conf
~# sudo sh -c 'echo "net.bridge.bridge-nf-call-iptables = 1 \nnet.ipv4.ip_forward = 1" >> /etc/sysctl.conf'
~# sudo sysctl -p
~# cat << EOF | tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
~# modprobe overlay
~# modprobe br_netfilter
~# cat << EOF | tee /etc/sysctl.d/k8s.conf
net.ipv4.tcp_keepalive_time=600
net.ipv4.tcp_keepalive_intvl=30
net.ipv4.tcp_keepalive_probes=10
net.ipv6.conf.all.disable_ipv6=1
net.ipv6.conf.default.disable_ipv6=1
net.ipv6.conf.lo.disable_ipv6=1
net.ipv4.neigh.default.gc_stale_time=120
net.ipv4.conf.all.rp_filter=0
net.ipv4.conf.default.rp_filter=0
net.ipv4.conf.default.arp_announce=2
net.ipv4.conf.lo.arp_announce=2
net.ipv4.conf.all.arp_announce=2
net.ipv4.ip_local_port_range= 45001 65000
net.ipv4.ip_forward=1
net.ipv4.tcp_max_tw_buckets=6000
net.ipv4.tcp_syncookies=1
net.ipv4.tcp_synack_retries=2
net.bridge.bridge-nf-call-ip6tables=1
net.bridge.bridge-nf-call-iptables=1
net.netfilter.nf_conntrack_max=2310720
net.ipv6.neigh.default.gc_thresh1=8192
net.ipv6.neigh.default.gc_thresh2=32768
net.ipv6.neigh.default.gc_thresh3=65536
net.core.netdev_max_backlog=16384
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_max_syn_backlog = 8096
net.core.somaxconn = 32768
fs.inotify.max_user_instances=8192
fs.inotify.max_user_watches=524288
fs.file-max=52706963
fs.nr_open=52706963
kernel.pid_max = 4194303
net.bridge.bridge-nf-call-arptables=1
vm.swappiness=0
vm.overcommit_memory=1
vm.panic_on_oom=0
vm.max_map_count = 262144
EOF
~# sysctl --system
安装配置时间同步
- 所有机器都要配置,同步互联网时间
~# apt -y install chrony
~# grep 'pool ntp.aliyun.com iburst maxsources 4' /etc/chrony/chrony.conf
# 一般配置多个,我这里配置一个
pool ntp.aliyun.com iburst maxsources 4
~# systemctl restart chrony
~# systemctl enable --now chrony
~# chronyc sources –v
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^* 203.107.6.88 2 6 17 20 -2162us[-2626us] +/- 23ms
主机名称解析
- 所有机器都要配置
- 我这里写的host文件
# cat /etc/hosts
192.168.139.161 k8s-master01
192.168.139.162 k8s-node01
禁用默认的防火墙服务
- 所有机器都要配置
~# ufw disable
~# ufw status
安装配置ipset、ipvsadm
~# apt install -y ipset ipvsadm
`配置ipvsadm模块加载`
~# cat << EOF | tee /etc/modules-load.d/ipvs.conf
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
ip_vs_sh
nf_conntrack
EOF
~# modprobe -- ip_vs
~# modprobe -- ip_vs_rr
~# modprobe -- ip_vs_wrr
~# modprobe -- ip_vs_sh
~# modprobe -- ip_vs_sh
~# modprobe -- nf_conntrack
安装程序包
- 所有机器都要配置
容器运行时:docker-ce和cri-dockerd(本次我选用)
~# apt-get install ca-certificates curl gnupg lsb-release
~# curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
~# add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
~# apt update
~# apt install docker-ce -y
- kubelet需要让docker容器引擎使用systemd作为CGroup的驱动,其默认值为cgroupfs,因而,我们还需要编辑docker的配置文件/etc/docker/daemon.json,添加如下内容,其中的registry-mirrors用于指明使用的镜像加速服务。
~# tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://dockerhub.timeweb.cloud",
"https://huecker.io",
"https://gigi8vhp.mirror.aliyuncs.com"
],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"max-concurrent-downloads": 10,
"max-concurrent-uploads": 5,
"log-opts": {
"max-size": "200m",
"max-file": "2"
},
"storage-driver": "overlay2",
"live-restore": true
}
EOF
~# systemctl daemon-reload
~# systemctl restart docker.service
~# systemctl enable docker.service
如果想要取登录取消SSL认证配置如下:
{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://dockerhub.timeweb.cloud",
"https://huecker.io",
"https://gigi8vhp.mirror.aliyuncs.com"
],
"insecure-registries": [
"xxx域名"
],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "200m"
},
"storage-driver": "overlay2"
}
安装cri-dockerd
- Kubernetes自v1.24移除了对docker-shim的支持,而Docker Engine默认又不支持CRI规范,因而二者将无法直接完成整合。为此,Mirantis和Docker联合创建了cri-dockerd项目,用于为Docker Engine提供一个能够支持到CRI规范的垫片,从而能够让Kubernetes基于CRI控制Docker 。
~# wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.17/cri-dockerd_0.3.17.3-0.ubuntu-jammy_amd64.deb
~# dpkg -i cri-dockerd_0.3.17.3-0.ubuntu-jammy_amd64.deb
~# systemctl status cri-docker.service
安装kubelet、kubeadm和kubectl
- 所有机器都要配置
- 自 v1.28版本开始,Kubernetes官方变更了仓库的存储路径及使用方式(不同的版本将会使用不同的仓库),并提供了向后兼容至v1.24版本。因此,对于v1.24及之后的版本来说,可以使用如下有别于传统配置的方式来安装相关的程序包。以本示例中要安装的v1.29版本为例来说,配置要使用的程序包仓库,需要使用的命令如下。如若需要安装其它版本,则将下面命令中的版本号**“v1.29”**予以替换即可。
~# apt-get update && apt-get install -y apt-transport-https
~# curl -fsSL https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.32/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
~# echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.32/deb/ /" | tee /etc/apt/sources.list.d/kubernetes.list
~# apt-get update
- 接下来,运行如下命令安装kubelet、kubeadm和kubectl等程序包
root@ubuntu2404:~# apt-cache madison kubeadm
kubeadm | 1.32.8-1.1 | https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.32/deb Packages
kubeadm | 1.32.7-1.1 | https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.32/deb Packages
kubeadm | 1.32.6-1.1 | https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.32/deb Packages
kubeadm | 1.32.5-1.1 | https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.32/deb Packages
kubeadm | 1.32.4-1.1 | https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.32/deb Packages
kubeadm | 1.32.3-1.1 | https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.32/deb Packages
kubeadm | 1.32.2-1.1 | https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.32/deb Packages
kubeadm | 1.32.1-1.1 | https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.32/deb Packages
kubeadm | 1.32.0-1.1 | https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.32/deb Packages
~# ~# apt-get install -y kubelet=1.32.8-1.1 kubeadm=1.32.8-1.1 kubectl=1.32.8-1.1
~# kubeadm version
kubeadm version: &version.Info{Major:"1", Minor:"29", GitVersion:"v1.29.4", GitCommit:"55019c83b0fd51ef4ced8c29eec2c4847f896e74", GitTreeState:"clean", BuildDate:"2024-04-16T15:05:51Z", GoVersion:"go1.21.9", Compiler:"gc", Platform:"linux/amd64"}
# 禁止自动更新
~# apt-mark hold kubeadm kubelet kubectl
(后续要更新执行:apt-mark unhold kubeadm kubelet kubectl 即可)
安装完成后,要确保kubeadm等程序文件的版本,这将也是后面初始化Kubernetes集群时需要明确指定的版本号。
整合kubelet和cri-dockerd(仅cri-dockerd需要)
- 所有机器都要配置
仅支持CRI规范的kubelet需要经由遵循该规范的cri-dockerd完成与docker-ce的整合。该步骤仅使用docker-ce和cri-dockerd运行时的场景中需要配置。
配置cri-dockerd
配置cri-dockerd,确保其能够正确加载到CNI插件。编辑/usr/lib/systemd/system/cri-docker.service文件,确保其[Service]配置段中的ExecStart的值类似如下内容。
ExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd:// --network-plugin=cni --cni-bin-dir=/opt/cni/bin --cni-cache-dir=/var/lib/cni/cache --cni-conf-dir=/etc/cni/net.d --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.10
需要添加的各配置参数(各参数的值要与系统部署的CNI插件的实际路径相对应):
- --network-plugin:指定网络插件规范的类型,这里要使用CNI;
- --cni-bin-dir:指定CNI插件二进制程序文件的搜索目录;
- --cni-cache-dir:CNI插件使用的缓存目录;
- --cni-conf-dir:CNI插件加载配置文件的目录;
- --pod-infra-container-image:Pod中的puase容器要使用的Image,默认为registry.k8s.io上的pause仓库中的镜像;不能直接获取到该Image时,需要明确指定为从指定的位置加载,例如“registry.aliyuncs.com/google_containers/pause:3.9”。
~# systemctl daemon-reload && systemctl restart cri-docker.service
配置kubelet
配置kubelet,为其指定cri-dockerd在本地打开的Unix Sock文件的路径,该路径一般默认为“/run/cri-dockerd.sock“。编辑文件/etc/sysconfig/kubelet,为其添加 如下指定参数。
提示:若/etc/sysconfig目录不存在,则需要先创建该目录
~# vim /etc/sysconfig/kubelet
KUBELET_KUBEADM_ARGS="--container-runtime=remote --container-runtime-endpoint=/run/cri-dockerd.sock"
需要说明的是,该配置也可不进行,而是直接在后面的各kubeadm命令上使用“--cri-socket unix:///run/cri-dockerd.sock”选项。
初始化master节点(在master01上完成如下操作)
在运行初始化命令之前先运行如下命令单独获取相关的镜像文件,而后再运行后面的kubeadm init命令,以便于观察到镜像文件的下载过程。
提示:若您选择使用的是docker-ce和cri-dockerd这一容器运行时环境,本文后续内容中使用的kubeadm命令,都需要额外添加“--cri-socket=unix:///var/run/cri-docker.sock”选项,以明确指定其所要关联的容器运行时。这是因为,docker-ce和cri-dockerd都提供了unix sock类型的socket地址,这会导致kubeadm在自动扫描和加载该类文件时无法自动判定要使用哪个文件。而使用containerd.io运行时,则不存在该类问题,因而无须明确指定
`列出需要下载的镜像`
~# kubeadm config images list
I0826 22:36:57.637727 7853 version.go:261] remote version is much newer: v1.33.4; falling back to: stable-1.32
registry.k8s.io/kube-apiserver:v1.32.8
registry.k8s.io/kube-controller-manager:v1.32.8
registry.k8s.io/kube-scheduler:v1.32.8
registry.k8s.io/kube-proxy:v1.32.8
registry.k8s.io/coredns/coredns:v1.11.3
registry.k8s.io/pause:3.10
registry.k8s.io/etcd:3.5.16-0
若需要从国内的Mirror站点下载Image,还需要在命令上使用“--image-repository”选项来指定Mirror站点的相关URL。例如,下面的命令中使用了该选项将Image Registry指向国内可用的Aliyun的镜像服务,其命令结果显示的各Image也附带了相关的URL。
~# kubeadm config images list --image-repository=registry.aliyuncs.com/google_containers
~# kubeadm config images list --kubernetes-version=v1.32.8 --image-repository=registry.aliyuncs.com/google_containers
registry.aliyuncs.com/google_containers/kube-apiserver:v1.32.8
registry.aliyuncs.com/google_containers/kube-controller-manager:v1.32.8
registry.aliyuncs.com/google_containers/kube-scheduler:v1.32.8
registry.aliyuncs.com/google_containers/kube-proxy:v1.32.8
registry.aliyuncs.com/google_containers/coredns:v1.11.3
registry.aliyuncs.com/google_containers/pause:3.10
registry.aliyuncs.com/google_containers/etcd:3.5.16-0
运行下面的命令即可下载需要用到的各Image。需要注意的是,如果需要从国内的Mirror站点下载Image,同样需要在命令上使用“--image-repository”选项来指定Mirror站点的相关URL和--cri-socket 指定cri运行时。
~# kubeadm config images pull --kubernetes-version=v1.32.8 --image-repository=registry.aliyuncs.com/google_containers --cri-socket unix:///run/cri-dockerd.sock
初始化
运行如下命令完成k8s-master01节点的初始化。需要注意的是,若使用docker-ce和cri-dockerd运行时,则还要在如下命令上明确配置使用“--cri-socket=unix:///var/run/cri-dockerd.sock”选项。
部署Kubernetes集群时,在kubeadm init命令上使用“--skip-phases=addon/kube-proxy”选项,以跳过kube-proxy的安装。
~# kubeadm init \
--control-plane-endpoint="192.168.139.161" \
--kubernetes-version=v1.32.8 \
--apiserver-advertise-address=192.168.139.161 \
--pod-network-cidr=10.244.0.0/16 \
--service-cidr=10.96.0.0/16 \
--upload-certs \
--image-repository=registry.aliyuncs.com/google_containers \
--skip-phases=addon/kube-proxy \
--cri-socket=unix:///var/run/cri-dockerd.sock
###
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/
You can now join any number of control-plane nodes running the following command on each as root:
kubeadm join 192.168.139.161:6443 --token tqk35e.r5x7aqutdgry590i \
--discovery-token-ca-cert-hash sha256:d6d42e8199eaf998c9ad5f8f4ff2fb7f403772376a94a69191922d178e053164 \
--control-plane --certificate-key 2aab06c52396a9acc503b78dfce5429ebdff0d95690036682ac6b49a3ecda713
Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use
"kubeadm init phase upload-certs --upload-certs" to reload certs afterward.
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.139.161:6443 --token tqk35e.r5x7aqutdgry590i \
--discovery-token-ca-cert-hash sha256:d6d42e8199eaf998c9ad5f8f4ff2fb7f403772376a94a69191922d178e053164
提示:无法访问registry.k8s.io时,同样可以在上面的命令中使用“--image-repository=registry.aliyuncs.com/google_containers”选项,以便从国内的镜像服务中获取各Image;
注意:若各节点未禁用Swap设备,还需要附加选项“--ignore-preflight-errors=Swap”,从而让kubeadm忽略该错误设定;
- --upload-certs: 做控制节点高可用,会自动分发证书到其他控制节点
- --image-repository: 指定镜像的repository
- --cri-socket: 指定cri的sock路径
加入节点到集群
其他master节点执行
kubeadm join 192.168.139.161:6443 --token tqk35e.r5x7aqutdgry590i \
--discovery-token-ca-cert-hash sha256:d6d42e8199eaf998c9ad5f8f4ff2fb7f403772376a94a69191922d178e053164 \
--control-plane --certificate-key 2aab06c52396a9acc503b78dfce5429ebdff0d95690036682ac6b49a3ecda713
所有node节点执行
root@k8s-node01:~# kubeadm join 192.168.139.161:6443 --token tqk35e.r5x7aqutdgry590i \
--discovery-token-ca-cert-hash sha256:d6d42e8199eaf998c9ad5f8f4ff2fb7f403772376a94a69191922d178e053164 \
--cri-socket=unix:///var/run/cri-dockerd.sock
安装网络插件 Cilium
下载 Cilium cli
root@k8s-master01:~# wget https://github.com/cilium/cilium-cli/releases/download/v0.18.4/cilium-linux-amd64.tar.gz
root@k8s-master01:~# tar xf cilium-linux-amd64.tar.gz -C /usr/local/bin/
安装cilium
示例1:使用默认的VXLAN模式,并自定义要使用的子网:(本次使用)
root@k8s-master01:~# cilium install \
--set kubeProxyReplacement=true \
--set ipam.mode=kubernetes \
--set ipam.operator.clusterPoolIPv4PodCIDRList=10.244.0.0/16 \
--set ipam.operator.clusterPoolIPv4MaskSize=24 \
--version 1.17.4
root@k8s-master01:~# kubectl -n kube-system get pods -l k8s-app=cilium
NAME READY STATUS RESTARTS AGE
cilium-jlsh9 1/1 Running 0 3m12s
cilium-s4j46 1/1 Running 0 3m12s
root@k8s-master01:~# cilium status --wait
示例2:使用原生路由模式
提示:云上主机未必支持该模式。
cilium install \
--set kubeProxyReplacement=true \
--set ipam.mode=kubernetes \
--set routingMode=native \
--set ipam.operator.clusterPoolIPv4PodCIDRList=10.244.0.0/16 \
--set ipam.operator.clusterPoolIPv4MaskSize=24 \
--set ipv4NativeRoutingCIDR=10.244.0.0/16 \
--set autoDirectNodeRoutes=true
说明:开启native routing模式后,通常应该明确指定支持原生路由的网段。
Cilium的高级特性
开启bpf masquerade:
--set bpf.masquerade=true
设置负载均衡模式: --set loadBalancer.mode=dsr 或者 --set loadBalancer.mode=hybrid 混合模式,即dsr和snat两种
开启DSR模式:--set autoDirectNodeRoutes=true
是否启用bpf LegacyRouting: --set bpf.hostLegacyRouting=true
启用Hubble及UI
通过cilium命令启用:
cilium hubble enable --ui
部署cilium时直接启用,在cilium命令上使用如下选项即可:
--set hubble.enabled="true" \
--set hubble.listenAddress=":4244" \
--set hubble.relay.enabled="true" \
--set hubble.ui.enabled="true"
同Prometheus对接:
--set prometheus.enabled=true \
--set operator.prometheus.enabled=true \
--set hubble.metrics.port=9665 \
--set hubble.metrics.enableOpenMetrics=true \
--set metrics.enabled="{dns:query;ignoreAAAA;destinationContext=pod-short,drop:sourceContext=pod;destinationContext=pod,tcp,flow,port-distribution,icmp,http}"
# 上面的设置,表示开启了hubble的metrics输出模式,并输出以上这些信息。默认情况下,Hubble daemonset会自动暴露metrics API给Prometheus。
--set hubble.metrics.enabled="{dns,drop,tcp,flow,port-distribution,icmp,httpV2:exemplars=true;labelsContext=source_ip\,source_namespace\,source_workload\,destination_ip\,destination_namespace\,destination_workload\,traffic_direction}"
#上面的设置,表示启用所有的指标。
示例:暴露所有指标的hubble配置,其它选项保持默认值即可
--set prometheus.enabled=true \
--set prometheus.serviceMonitor.enabled=true \
--set operator.prometheus.enabled=true \
--set operator.prometheus.serviceMonitor.enabled=true \
--set hubble.enabled=true \
--set hubble.metrics.enableOpenMetrics=true \
--set hubble.ui.enabled=true \
--set hubble.relay.enabled=true \
--set hubble.metrics.enabled="{dns,drop,tcp,flow,port-distribution,icmp,httpV2:exemplars=true,labelsContext=source_ip,labelsContext=source_namespace,labelsContext=source_workload,labelsContext=destination_ip,labelsContext=destination_namespace,labelsContext=destination_workload,labelsContext=traffic_direction}"
验证集群是否可用
root@k8s-master01:~# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master01 Ready control-plane 36m v1.32.8
k8s-node01 Ready <none> 31m v1.32.8
k8s-node02 Ready <none> 2m55s v1.32.8
验证网络
root@k8s-master01:~# kubectl create deployment demoapp \
--image=registry.cn-zhangjiakou.aliyuncs.com/tanghao429/tanghao:demoapp.v1.0 \
--replicas=1
root@k8s-master01:~# kubectl create service nodeport demoapp --tcp=80:80
root@k8s-master01:~# kubectl get svc -l app=demoapp
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demoapp NodePort 10.109.205.14 <none> 80:31930/TCP 15s
root@k8s-master01:~# kubectl run client-$RANDOM \
--image=registry.cn-zhangjiakou.aliyuncs.com/tanghao-public/admin-box:v1.2 -it \
--command -- /bin/sh
root@client-3327 # while true; do curl demoapp.default.svc; sleep 1; done
iKubernetes demoapp v1.0 !! ClientIP: 10.244.2.104, ServerName: demoapp-75c9b5556b-t5ns7, ServerIP: 10.244.2.249!
iKubernetes demoapp v1.0 !! ClientIP: 10.244.2.104, ServerName: demoapp-75c9b5556b-t5ns7, ServerIP: 10.244.2.249!
k8s项目补全
`方法一` 只在当前终端生效
source <(kubectl completion bash)
`方法二`
echo'source <(kubectl completion bash)' >> ~/.bashrc # 在您的 bash shell 中永久的添加自动补全
以下为可选步骤
MetalLB
MetalLB是一款开源的云原生负载均衡器实现,可以在基于裸金属服务器或虚拟机的Kubernetes 环境中使用LoadBalancer类型的Service对外暴露服务。
MetalLB核心功能的实现依赖于两种机制:
- 地址分配:基于指定的地址池进行分配;
- 对外公告:让集群外部的网络了解新分配的IP地址,MetalLB使用ARP、NDP或BGP实现
部署MetalLB
kube-proxy工作于ipvs模式时,必须要使用严格ARP(StrictARP)模式,因此,部署MetalLB之前,需要事先运行如下命令,配置kube-proxy。注意 我们没有使用 kube-proxy 下面这个步骤可以忽略
root@k8s-master01:~# kubectl get configmap kube-proxy -n kube-system -o yaml | sed -e "s/strictARP: false/strictARP: true/" | kubectl apply -f - -n kube-system
随后,运行如下命令,即可部署MetalLB至Kubernetes集群,本示例中部署的版本为“v0.15.2”。
root@k8s-master01:~# kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.15.2/config/manifests/metallb-native.yaml
MetalLB默认将其各组件部署于metallb-system名称空间下,运行如下命令,打印各Pod的运行状态 。
root@k8s-master01:~# kubectl get pods -n metallb-system
NAME READY STATUS RESTARTS AGE
controller-58fdf44d87-df4r9 1/1 Running 0 3m35s
speaker-jvq4m 1/1 Running 0 3m35s
speaker-tqtfk 1/1 Running 0 3m35s
speaker-v88gk 1/1 Running 0 3m35s
待如上各Pod转为Running状态后,即可进行后续的步骤。
创建地址池和二层公告机制
- MetalLB提供了名为IPAddressPool的自定义资源类型,它允许用户以声明式方式定义用于分给LoadBalancer的IP地址范围。下面是一个IPAddressPool资源示例,它所选定的地址范围是当前集群节点网络中的一个空闲地址空间。
- 将地址池中的某地址配置在某节点上,并以externalIP的形式分配给某LoadBalancer使用之前,需要向整个本地网络通告该地址相关的ARP地址信息。具体使用时,请将如下示例中的interfaces修改为集群中各节点上实际使用的接口名称
root@k8s-master01:~# mkdir -p ~/MetalLB-yml && cd ~/MetalLB-yml
root@k8s-master01:~# cat > ~/MetalLB-yml/iptool.yaml << 'EOF'
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: localip-pool
namespace: metallb-system
spec:
addresses:
- 192.168.139.40-192.168.139.70 # 网段跟node节点保持一致
autoAssign: true
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: localip-pool-l2a
namespace: metallb-system
spec:
ipAddressPools:
- localip-pool
interfaces:
- eth0
EOF
root@k8s-master01:~# kubectl apply -f MetalLB-yml/iptool.yaml
创建LB Service进行测试
创建Deployment和LoadBalancer Service,测试地址池是否已经能正常向Service分配LoadBalancer IP。
root@k8s-master01:~# kubectl create deployment demoapp \
--image=registry.cn-zhangjiakou.aliyuncs.com/tanghao429/tanghao:demoapp.v1.0 \
--replicas=2
root@k8s-master01:~# kubectl create service loadbalancer demoapp --tcp=80:80
运行如下命令,查看service资源对象demoapp上是否自动获得了External IP。
root@k8s-master01:~# kubectl get service demoapp
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demoapp LoadBalancer 10.109.192.10 192.168.139.40 80:32599/TCP 39s
随后,即可于集群外部的客户端上通过IP地址“192.168.139.40”对demoapp服务发起访问测试。

清理
删除部署的测试目的Deployment和LoadBalancer Server。
root@k8s-master01:~# kubectl delete service/demoapp deployment/demoapp
Ingress Nginx
Ingress Nginx是由Kubernetes社区维护的Ingress Controller的实现。以v1.13.1版本为例,运行下面的命令,即可完成部署。需要特别说明的是,Ingress Nginx的相关Image位于registry.k8s.io服务上,该服务通常需要通过代理才能进行访问。
# kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.13.1/deploy/static/provider/cloud/deploy.yaml
# kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-controller-b57765c6-c7xt5 1/1 Running 0 2m7s
运行下面的命令,查看相关Service的状态信息。如果部署了MetalLB或OpenELB一类的LoadBalancer Service的实现,其External-IP应该可以获得EIP可用分配范围内的一个地址,类似如下命令及其结果所示。
root@k8s-master01:~/MetalLB-yml# kubectl get services -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 10.109.195.35 192.168.139.40 80:31462/TCP,443:31724/TCP 2m31s
ingress-nginx-controller-admission ClusterIP 10.98.91.110 <none> 443/TCP 2m31s
随后,我们即可透过Ingress向集群外部发布应用。


文章评论