搭建K8s集群
官网:https://kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
使用kubeadm搭建一个3台机器组成的k8s集群,1台master节点,2台worker节点
如果大家机器配置不够,也可以使用在线的,或者minikube的方式或者1个master和1个worker
配置要求:
3 台linux主机或者虚拟机
每台机器 4 GB 或更多的 RAM (如果少于这个数字将会影响你应用的运行内存)
每台机器 2 CPU 核或更多
集群中的所有机器的网络彼此均能相互连接(公网和内网都可以)
节点之中不可以有重复的主机名、MAC 地址或 product_uuid。请参见这里 了解更多详细信息。
开启机器上的某些端口。请参见这里 了解更多详细信息。
禁用交换分区。为了保证 kubelet 正常工作,你 必须 禁用交换分区。
本篇基于 CentOS-8 来搭建
系统初始化 设置系统主机名以及 Host 文件的相互解析
(1) master
1 2 3 4 5 6 sudo hostnamectl set-hostname m vi /etc/hosts 192.168.8.51 m 192.168.8.61 n1 192.168.8.62 n2
(2) 两个 node
1 2 3 4 5 6 7 sudo hostnamectl set-hostname n1 sudo hostnamectl set-hostname n2 vi /etc/hosts 192.168.8.51 m 192.168.8.61 n1 192.168.8.62 n2
(3) 使用ping测试一下
安装依赖包 1 yum install -y npt ipvsadm ipset jq iptables curl sysstat libseccomp wget vim net-tools git
设置防火墙为 Iptables 并设置空规则 1 systemctl stop firewalld && systemctl disable firewalld
安装 iptables 管理工具 && 启动它 && 设置为开机自启 && 清空它的规则 && 保存空规则为默认规则
1 yum install -y iptables-services && systemctl start iptables && systemctl enable iptables && iptables -F && service iptables save
关闭 swap 并把 swap 分区永久关闭
在安装 k8s 的时候,它初始化的时候会检测 swap 是否关闭
因为如果开启了虚拟内存的话,pod 就有可能会放在虚拟内存去运行,会大大降低性能。
1 swapoff -a && sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
关闭 SELINUX 并把 SELINUX 永久关闭 1 setenforce 0 && sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
!!!重启机器 reboot
调整内核参数
这里面有三条是必须的,其他的是做了一些优化,不设置也是可以的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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-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 # 关闭 ipv6 的协议——必须 net.netfilter.nf_conntrack_max=2310720 EOF sudo sysctl --system
调整系统时区 1 2 3 4 5 6 7 8 9 # 设置系统时区为 中国/上海 timedatectl set-timezone Asia/Shanghai # 将当前的 UTC 时间写入硬件时钟 timedatectl set-local-rtc 0 # 重启依赖于系统时间的服务 systemctl restart rsyslog systemctl restart crond
关闭系统不需要的服务 关闭邮件服务,尽量减少服务器不必要的压力
1 systemctl stop postfix && systemctl disable postfix
设置 rsyslogd 和 systemd journald 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 # 持久化保存日志的目录 mkdir /var/log/journal mkdir /etc/systemd/journald.conf.d cat > /etc/systemd/journald.conf.d/99-prophet.conf <<EOF [Journal] # Storage=persistent # Compress=yes SyncIntervalSec=5m RateLimitInterval=30s RateLimitBurst=1000 # SystemMaxUse=10G # SystemMaxFileSize=200M # MaxRetentionSec=2week # ForwardToSyslog=no EOF systemctl restart systemd-journald
Kubernetes 部署安装 kube-proxy 开启 ipvs 的前置条件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 modprobe br_netfilter cat > /etc/sysconfig/modules/ipvs.modules <<EOF # !/bin/bash modprobe -- ip_vs modprobe -- ip_vs_rr modprobe -- ip_vs_wrr modprobe -- ip_vs_sh modprobe -- nf_conntrack_ipv4 EOF chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4 # 如果报错 modprobe: FATAL: Module nf_conntrack_ipv4 not found in directory # 说明 高版本的centos内核nf_conntrack_ipv4被nf_conntrack替换了,所以装不了 # 使用以下命令替换 modprobe -- nf_conntrack
安装 Kubeadm (主从配置)
(1) 三个节点都安装 kubeadm kubectl kubelet
本文基于 centOS 来安装,如果是其他发行版,请根据来操作官方文档
1 2 3 4 5 6 7 8 9 10 11 12 cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://pkgs.k8s.io/core:/stable:/v1.30/rpm/ enabled=1 gpgcheck=1 gpgkey=https://pkgs.k8s.io/core:/stable:/v1.30/rpm/repodata/repomd.xml.key exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni EOF sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes systemctl start kubelet && systemctl enable kubelet.service
(2) 修改 containerd 的配置
使用 k8s 默认容器,而不是 docker,因为 自 1.24 版起,Dockershim 已从 Kubernetes 项目中移除,详情可参考官方文档
1 2 3 4 5 6 7 8 9 10 11 12 13 14 # 将 containerd 的默认配置文件保存下来 containerd config default > /etc/containerd/config.toml # 修改里面的 [plugins."io.containerd.grpc.v1.cri" .containerd.runtimes.runc.options] 下面的 SystemdCgroup ,将 false 改为 true sudo sed -i -e "s|SystemdCgroup = false|SystemdCgroup = true|g" /etc/containerd/config.toml systemctl daemon-reload systemctl restart containerd # 检查一下容器命令是否报错 crictl ps # 如果警告 WARN[0000] image connect using default endpoints: **** As the default settings are now deprecated, you should set the endpoint instead. crictl config --set runtime-endpoint=unix:///var/run/containerd/containerd.sock
拉取镜像节点
需要科学上网
1 kubeadm config images pull
初始化主节点
注意: 此操作是在主节点上进行
1 2 3 4 # 将 k8s 默认的初始化文件打印到 kubeadm-config.yaml 中 kubeadm config print init-defaults > kubeadm-config.yaml # 然后进行编辑 vim kubeadm-config.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # 然后修改 ip 地址为当前服务器的地址 localAPIEndpoint: advertiseAddress: # 将这里改为目前这个服务器的 ip 地址 bindPort: 6443 # 端口默认不需要动 networking: dnsDomain: cluster.local podSubnet: "10.244.0.0/16" # 这里加一行,因为 flannel 的默认网段就是这个网段 serviceSubnet: 10.96.0.0/12 # 并且在最后面添加下面几行,粘贴进去以后记得检查文件格式,粘贴的 tab 格式可能有问题 # 是为了把默认的调度方式改为 ipvs 调度 --- apiVersion: kubeproxy.config.k8s.io/v1alpha1 kind: KubeProxyConfiguration mode: ipvs
1 2 3 4 # 指定从刚才我们配置的文件进行初始化安装 kubeadm init --config=kubeadm-config.yaml --upload-certs | tee kubeadm-init.log # 若要重新初始化集群状态请查看下面的 重置 master,然后再进行上述操作
根据上面执行结果的提示执行脚本配置权限 ps: 每次init都需要重新设置
1 2 3 mkdir -p $HOME/.kube cp -i /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config
为了使用更便捷,启用 kubectl 命令的自动补全功能 1 2 3 4 yum install -y bash-completion source /usr/share/bash-completion/bash_completion source <(kubectl completion bash) echo "source <(kubectl completion bash)" >> ~/.bashrc
重置 master (如果需要的话) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # 初始化失败用这个重置 kubeadm reset # 关闭,删除网卡cni0 ifconfig cni0 down; ip link delete cni0 # 关闭;删除网卡flannel.1 ifconfig flannel.1 down ;ip link delete flannel.1 ifconfig kube-ipvs0 down; ip link delete kube-ipvs0 ifconfig dummy0 down; ip link delete dummy0 # 清空iptables转发规则 iptables --flush; iptables -tnat --flush # cni 配置删除 rm -rf /var/lib/cni/ # cni 网络配置删除 rm -f /etc/cni/net.d/* # 删除kube配置 rm -rf ~/.kube/
将其余节点加入主节点
kubeadm join 的信息可以在 kubeadm-init.log 中查看
在别的节点执行日志中 kubeadm join 的命令即可,类似以下
1 2 kubeadm join 192.168.0.51:6443 --token yu1ak0.2dcecvmpozsy8loh \ --discovery-token-ca-cert-hash sha256:5c4a69b3bb05b81b675db5559b0e4d7972f1d0a61195f217161522f464c307b0
可以在 master 检查集群信息
查看是否成功
部署网络
使用 flannel
1 2 3 4 5 6 7 8 9 10 11 12 # 创建文件夹,将 k8s 一些重要的文件移进去 mkdir -p install-k8s/core mv kubeadm-init.log kubeadm-config.yaml install-k8s/core/ cd install-k8s # 创建插件文件夹 mkdir -p plugin/flannel cd plugin/flannel wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml kubectl create -f kube-flannel.yml mv install-k8s /usr/local/
配置私有仓库【可选,根据自己需要】 前置操作
同样需要在一台新服务器上安装好 docker
docker 默认是 https 协议的访问,我们可以购买 https 证书,也可以造一个假的。
如果是假的 https 的话,就需要添加下面这一句话来告诉 docker,我这个可以正常访问
同样,所有的 k8s 节点都需要添加这句话
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 vim /etc/docker/daemon.json # 在原先的配置文件下添加一句话 "insecure-registries" : ["https://hub.dragon.com" ] { "exec-opts": ["native.cgroupdriver=systemd"], "log-dirver": "json-file", "log-opts": { "max-size": "100m" }, "insecure-registries": ["https://hub.dragon.com"] # 这里的域名是自己的私有仓库的域名,如果没有,可以使用改 host 的方式假装实现 } # 然后重启 systemctl restart docker # 所有节点的 host 文件添加私有仓库的 ip 解析,ip 为 私有仓库的ip,域名为上面添加的域名 # 自己的 Windows 电脑的 host 文件也添加以下,这样等安装完成以后在浏览器输入域名就可以访问了 192.168.1.1 hub.dragon.com
下载安装包 1 2 3 4 5 6 7 8 9 10 11 12 # 下载 docker-compose curl -L https://github.com/docker/compose/releases/download/1.9.0/docker-compose-`uname -s`-`uname -m` > /usr/local /bin/docker-compose chmod a+x /usr/local/bin/docker-compose # 下载安装包 wget https://github.com/vmware/harbor/releases/download/v1.2.0/harbor-offline-installer-v1.2.0.tgz tar -zxvf harbor-offline-installer-v1.2.0.tgz # 将 harbor 目录移动到 usr/local 下 mv harbor /usr/local
配置harbor.cfg 以下为 必选参数
hostname :目标的主机名或者完全限定域名
ui_url_protocol :http 或 https。默认为 http
db_password :用于 db_auth 的 MySQL 数据库的根密码。更改此密码进行任何生产用途
max_job_workers :(默认值为3)作业服务中的复制工作人员的最大数量。对于每个映像复制作业, 工作人员将存储库的所有标签同步到远程目标。增加此数字允许系统中更多的并发复制作业。但是,由于每个工 作人员都会消耗一定数量的网络/ CPU/IO资源,请根据主机的硬件资源,仔细选择该属性的值
customize_crt :(on 或 off。默认为 on)当此属性打开时,prepare 脚本将为注册表的令牌的生成/验证创 建私钥和根证书
ssl_cert :SSL证书的路径,仅当协议设置为 https 时才应用
ssl_cert_key :SSL密钥的路径,仅当协议设置为 https 时才应用
secretkey_path :用于在复制策略中加密或解密远程注册表的密码的密钥路径
1 2 3 4 5 6 7 8 9 10 11 12 cd /usr/local/harbor vim harbor.cfg # hostname 也就是之前我们在 daemon.json 里配置的那个域名 hostname = hub.dragon.com # 协议改成 https ui_url_protocol = https # 其他的用默认的就ok # 然后创建一下 ss_cert 参数需要的目录 mkdir -p /data/cert
创建 https 证书以及配置相关目录权限 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 # 生成私钥 然后输入密码 openssl genrsa -des3 -out server.key 2048 # 创建证书 csr 请求,输入之前私钥的密码,然后根据提示一步一步填写 # Country Name 国家 CN # State or Province Name 省 BJ # Locality Name 市 BJ # Organization Name 组织 随便写 # Organizational Unit Name 机构 和上面一样 # Common Name 域名 hub.dragon.com # Email Address 邮箱 openssl req -new -key server.key -out server.csr # 备份私钥 cp server.key server.key.org # docker 在引导的时候如果私钥是有密码的话,会出问题,导致引导不成功。 # 所以在这里要退出一下密码,这样私钥就不包含密码了 openssl rsa -in server.key.org -out server.key # 签名,生成证书 openssl x509 -req -days 365 -in server.csr-signkey server.key -out server.crt # 然后赋予一下权限 chmod a+x * cd /usr/local/harbor ./install.sh
测试 浏览器输入 hub.dragon.com
默认账号是 admin 密码在配置文件中可以看到,默认是 Harbor12345
然后让 k8s 节点的 docker 登录到私有仓库
1 docker login https://hub.dragon.com
然后就可以玩了