1. 准备环境
| 角色 | IP | 系统 |
|---|---|---|
| k8s-master | 192.16.16.130 | Ubuntu 20.04.3 LTS (GNU/Linux 5.4.0-81-generic x86_64)服务器版 |
| k8s-node1 | 192.16.16.131 | Ubuntu 20.04.3 LTS (GNU/Linux 5.4.0-81-generic x86_64)服务器版 |
| k8s-node2 | 192.16.16.132 | Ubuntu 20.04.3 LTS (GNU/Linux 5.4.0-81-generic x86_64)服务器版 |
系统优化
#1.#安装依赖
sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
apt -y install ipvsadm ipset sysstat conntrack
#2.# 关闭 swap 内存
sudo vi /etc/fstab
swapoff -a
#3.#关闭防火墙
systemctl stop ufw
systemctl disable ufw
#4.#linux系统文件描述符数量
echo '* - nofile 65536 ' >>/etc/security/limits.conf
echo '* - nproc 65536' >>/etc/security/limits.conf
#5.# 配置ip_vs转发
# Enable kernel modules
sudo modprobe overlay && \
sudo modprobe br_netfilter
#创建目录
mkdir ~/k8s-init/
#写入参数配置
tee ~/k8s-init/ipvs.modules <<'EOF'
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_lc
modprobe -- ip_vs_lblc
modprobe -- ip_vs_lblcr
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- ip_vs_dh
modprobe -- ip_vs_fo
modprobe -- ip_vs_nq
modprobe -- ip_vs_sed
modprobe -- ip_vs_ftp
modprobe -- ip_vs_sh
modprobe -- ip_tables
modprobe -- ip_set
modprobe -- ipt_set
modprobe -- ipt_rpfilter
modprobe -- ipt_REJECT
modprobe -- ipip
modprobe -- xt_set
modprobe -- br_netfilter
modprobe -- nf_conntrack
EOF
chmod 755 ~/k8s-init/ipvs.modules && sudo bash ~/k8s-init/ipvs.modules
sudo cp ~/k8s-init/ipvs.modules /etc/profile.d/ipvs.modules.sh
lsmod | grep -e ip_vs -e nf_conntrack
#6.# Kernel 参数调整
mkdir ~/k8s-init/
cat > ~/k8s-init/kubernetes-sysctl.conf <<EOF
# iptables 网桥模式开启
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
# 禁用 ipv6 协议
net.ipv6.conf.all.disable_ipv6=1
# 启用ipv4转发
net.ipv4.ip_forward=1
# net.ipv4.tcp_tw_recycle=0 #Ubuntu 没有参数
# 禁止使用 swap 空间,只有当系统 OOM 时才允许使用它
vm.swappiness=0
# 不检查物理内存是否够用
vm.overcommit_memory=1
# 不启 OOM
vm.panic_on_oom=0
# 文件系统通知数(根据内存大小和空间大小配置)
fs.inotify.max_user_instances=8192
fs.inotify.max_user_watches=1048576
# 文件件打开句柄数
fs.file-max=52706963
fs.nr_open=52706963
net.netfilter.nf_conntrack_max=2310720
# tcp keepalive 相关参数配置
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl =15
net.ipv4.tcp_max_tw_buckets = 36000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_orphans = 327680
net.ipv4.tcp_orphan_retries = 3
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 16384
# net.ipv4.ip_conntrack_max = 65536 # Ubuntu 没有参数
net.ipv4.tcp_timestamps = 0
net.core.somaxconn = 32768
EOF
sudo cp ~/k8s-init/kubernetes-sysctl.conf /etc/sysctl.d/99-kubernetes.conf
sudo sysctl -p /etc/sysctl.d/99-kubernetes.conf
# 7.nftables 模式切换
# 在 Linux 中 nftables 当前可以作为内核 iptables 子系统的替代品,该工具可以充当兼容性层其行为类似于 iptables 但实际上是在配置 nftables。
# apt list | grep "nftables/focal"
# nftables/focal 0.9.3-2 amd64
# python3-nftables/focal 0.9.3-2 amd64
# iptables 旧模式切换 (nftables 后端与当前的 kubeadm 软件包不兼容, 它会导致重复防火墙规则并破坏 kube-proxy, 所则需要把 iptables 工具切换到“旧版”模式来避免这些问题)
sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
# sudo update-alternatives --set arptables /usr/sbin/arptables-legacy # PS: # Ubuntu 20.04 TLS 无该模块
# sudo update-alternatives --set ebtables /usr/sbin/ebtables-legacy # PS: # Ubuntu 20.04 TLS 无该模块 作者:WeiyiGeek # #https://www.bilibili.com/read/cv16278587/ 出处:bilibil
#8.#设置 rsyslogd 和 systemd journald只保留一个日志工具
sudo mkdir -pv /var/log/journal/ /etc/systemd/journald.conf.d/
sudo tee /etc/systemd/journald.conf.d/99-prophet.conf <<'EOF'
[Journal]
# 持久化保存到磁盘
Storage=persistent
# 压缩历史日志
Compress=yes
SyncIntervalSec=5m
RateLimitInterval=30s
RateLimitBurst=1000
# 最大占用空间 10G
SystemMaxUse=10G
# 单日志文件最大 100M
SystemMaxFileSize=100M
# 日志保存时间 2 周
MaxRetentionSec=2week
# 不将日志转发到syslog
ForwardToSyslog=no
EOF
cp /etc/systemd/journald.conf.d/99-prophet.conf ~/k8s-init/journald-99-prophet.conf
sudo systemctl restart systemd-journald
#9.# 设置时区
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
#10. 时间同步
if ! crontab -l |grep ntpdate &>/dev/null ; then
(echo "* 1 * * * ntpdate time.windows.com >/dev/null 2>&1";crontab -l) |crontab
fi
echo '######系统初始化完成&&&即将重启系统#######'
sleep 5
reboot
3. 安装Docker/kubeadm/kubelet
Kubernetes默认CRI(容器运行时)为Docker,因此先安装Docker。
3.1 安装Docker
一、设置apt源
1、Update the apt package index and install packages to allow apt to use a repository over HTTPS:
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
2、Add Docker’s official GPG key:
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
3、Use the following command to set up the repository:
echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
4、Update the apt package index:
sudo apt-get update
二、安装dockers
# 1.卸载旧版本
sudo apt-get remove docker docker-engine docker.io containerd runc
# 2.指定版本安装
查看可安装的版本
apt-cache madison docker-ce
指定版本
apt-get install -y docker-ce=5:20.10.16~3-0~ubuntu-focal docker-ce-cli=5:20.10.16~3-0~ubuntu-focal containerd.io
配置镜像下载加速器:
sudo mkdir -p /etc/docker
cat > /etc/docker/daemon.json <<EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
"insecure-registries": [
"images.nancal.com:8000",
"images.houchangzao.com",
"harbor.nancalcloud.com",
"https://n754gaxs.mirror.aliyuncs.com"
],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
}
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
3.2 添加K8S阿里云apt源
使得 apt 支持 ssl 传输
apt-get update && apt-get install -y apt-transport-https
下载 gpg 密钥 这个需要root用户否则会报错
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
添加 k8s 镜像源 这个需要root用户否则会报错
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
更新源列表
apt-get update
3.3 安装kubeadm,kubelet和kubectl
由于版本更新频繁,这里指定版本号部署:
apt-cache madison kubelet
apt-get install -y kubelet=1.21.0-00 kubeadm=1.21.0-00 kubectl=1.21.0-00
systemctl enable kubelet
离线部署包下载
apt-get install --download-only kubelet=1.21.0-00 kubeadm=1.21.0-00 kubectl=1.21.0-00 ,应用保存路径 /var/cache/apt/archives
4. 部署Kubernetes Master
在192.16.16.130(Master)执行。
$ kubeadm init \
--apiserver-advertise-address=192.16.16.130 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.21.0 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16 \
--ignore-preflight-errors=all
kubectl edit configmap kube-proxy -n kube-system
#把原来mode配置为ipvs,默认是空
42 kind: KubeProxyConfiguration
43 metricsBindAddress: ""
44 mode: "ipvs"
45 nodePortAddresses: null
- --apiserver-advertise-address 集群通告地址
- --image-repository 由于默认拉取镜像地址k8s.gcr.io国内无法访问,这里指定阿里云镜像仓库地址
- --kubernetes-version K8s版本,与上面安装的一致
- --service-cidr 集群内部虚拟网络,Pod统一访问入口
- --pod-network-cidr Pod网络,,与下面部署的CNI网络组件yaml中保持一致
- --service-node-port-range=1-65535 端口范围
建议使用配置文件引导:
##查看镜像
kubeadm config images list --kubernetes-version=v1.21.1 --image-repository registry.aliyuncs.com/google_containers
##获取kubeadm文件
kubeadm config print init-defaults > kubeadm.yaml
##修改文件
$ vi kubeadm.conf
apiVersion: kubeadm.k8s.io/v1beta2
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 192.16.16.130
bindPort: 6443
nodeRegistration:
criSocket: /var/run/dockershim.sock
name: k8s-master01
taints:
- effect: NoSchedule
key: node-role.kubernetes.io/master
---
apiServer:
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns:
type: CoreDNS
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: 1.21.1
networking:
dnsDomain: cluster.local
podSubnet: "10.244.0.0/16"
serviceSubnet: 10.96.0.0/12
scheduler: {}
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs
执行文件
$ kubeadm init --config=kubeadm.conf --ignore-preflight-errors=all
拷贝kubectl使用的连接k8s认证文件到默认路径:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready master 2m v1.21.1
修改端口范围
vi /etc/kubernetes/manifests/kube-apiserver.yaml
sed -i '30a \ \ \ \ - --service-node-port-range=1-65535' /etc/kubernetes/manifests/kube-apiserver.yaml
sed -i '44a \ \ \ \ - --feature-gates=RemoveSelfLink=false' /etc/kubernetes/manifests/kube-apiserver.yaml
修改可以用nfs创建pvc
kubectl edit deployment coredns -n kube-system
镜像
改为:
registry.aliyuncs.com/google_containers/coredns:v1.8.0
kuborad获取token
在master上执行命令获取token
echo $(kubectl -n kube-system get secret $(kubectl -n kube-system get secret | grep kuboard-user | awk '{print $1}') -o go-template='{{.data.token}}' | base64 -d)
复制token之后点击登录
Node 节点后期添加命令获取添加命令
kubeadm token create --print-join-command
配置kube-proxy开启IPVS模式
kubectl edit configmap kube-proxy -n kube-system
#把原来mode配置为ipvs,默认是空
42 kind: KubeProxyConfiguration
43 metricsBindAddress: ""
44 mode: "ipvs"
45 nodePortAddresses: null
#删除pod重新运行
kubectl delete pod -n kube-system kube-proxy-mtkns
#查看状态
ipvsadm -Ln
问题处理:如果集群一直出现未就绪状态,需要将flannel程序复制到 /opt/cni/net.d/
5. 加入Kubernetes Node
在192.168.31.62/63(Node)执行。
向集群添加新节点,执行在kubeadm init输出的kubeadm join命令:
$ kubeadm join 192.16.16.130:6443 --token esce21.q6hetwm8si29qxwn \
--discovery-token-ca-cert-hash sha256:00603a05805807501d7181c3d60b478788408cfe6cedefedb1f97569708be9c5
默认token有效期为24小时,当过期之后,该token就不可用了。这时就需要重新创建token,操作如下:
$ kubeadm token create
$ kubeadm token list
$ openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
63bca849e0e01691ae14eab449570284f0c3ddeea590f8da988c07fe2729e924
$ kubeadm join 192.16.16.130:6443 --token nuja6n.o3jrhsffiqs9swnu --discovery-token-ca-cert-hash sha256:63bca849e0e01691ae14eab449570284f0c3ddeea590f8da988c07fe2729e924
kubeadm token create --print-join-command
6. 部署Flannel
Flannel是CoreOS维护的一个网络组件,Flannel为每个Pod提供全局唯一的IP,Flannel使用ETCD来存储Pod子网与Node IP之间的关系。flanneld守护进程在每台主机上运行,并负责维护ETCD信息和路由数据包。
#使用gitee,github因为网络原因可能无法正常下载
git clone --depth 1 https://gitee.com/CaiJinHao/flannel.git
#安装
kubectl apply -f flannel/Documentation/kube-flannel.yml
#查看pod状态,当flannel状态为Running的时候就表示安装完成
kubectl get pod -n kube-system
7. 测试kubernetes集群
- 验证Pod工作
- 验证Pod网络通信
- 验证DNS解析
在Kubernetes集群中创建一个pod,验证是否正常运行:
$ kubectl create deployment nginx --image=nginx
$ kubectl expose deployment nginx --port=80 --type=NodePort
$ kubectl get pod,svc
访问地址:http://NodeIP:Port