参见:https://www.cnblogs.com/syuee/p/15057847.html
1、集群安装
一、 主机准备
1、设置主机名以及host文件的相互解析:
hostnamectl set-hostname k8s-master01
vi /etc/hosts 192.168.66.10 k8s-master01 (在大型环境建议通过DNS的方式,让主机名和ip能够相互解析)
2、安装必要的依赖包
yum install -y conntrack ntpdate ntp ipvsadm ipset jq iptables curl sysstat libseccomp wget vim net-tools git
3、设置防火墙为Iptables并设置空规则
iptables 是一个功能强大的网络包过滤和转发工具,它可以帮助管理员配置和管理系统的网络安全策略,实现防火墙、网络地址转换和数据包修改等功能。通过合理配置 iptables 规则,可以增强系统的网络安全性和灵活性。
systemctl stop firewalld && systemctl disable firewalld
yum -y install ipatbles-service && systemctl start iptables && systemctl enable ipatbles && ipatbles -f && service ipatables save
(安装 iptables 服务,启动该服务。并设置 iptables 服务在系统启动时自动启动。最后,它会刷新规则、保存配置)
4、关闭SELINUX
swapoff -a && sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
(禁用系统上的所有 Swap 分区。在 /etc/fstab 文件中找到包含关键字 "swap" 的行,并将其替换为以 "#" 开头的注释行。)
setenforce 0 && sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
(这个命令用于将 SELinux 安全模块设置为 "Permissive" 模式。SELinux 是一种强制访问控制(MAC)机制,用于加强 Linux 系统的安全性。通过将 SELinux 设置为 "Permissive" 模式,系统仍然会记录违规行为,但不会阻止它们。这样可以临时禁用 SELinux 的强制访问控制,以便进行一些需要临时关闭 SELinux 的操作。将 /etc/selinux/config 文件中的 SELINUX 参数的值修改为 "disabled",从而永久禁用 SELinux。)
5、调整内核参数,对于k8s
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 #关闭IPV6协议
net.netfilter.nf_conntrack_max=2310720
EOF
cp kubernetes.conf /etc/sysctl.d/kubernetes.conf
sysctl -p /etc/sysctl.d/kubernetes.conf 手动刷新生效
6、调整系统时区
# 设置系统时区为 中国/上海
timedatectl set-timezone Asia/Shanghai
# 将当前的 UTC 时间写入硬件时钟
timedatectl set-local-rtc 0
# 重启依赖于系统时间的服务
systemctl restart rsyslog
systemctl restart crond
7、关闭系统不需要服务
Postfix 是一个邮件传输代理(MTA),它用于发送、接收和路由电子邮件。
systemctl stop postfix && systemctl disable postfix
8、设置 rsyslogd 和 systemd journald
rsyslogd 和 systemd journald 是两种不同的日志管理系统,用于收集、存储和管理系统日志。主要区别:
rsyslogd 是传统的 syslog 系统,而 systemd journald 是 systemd 系统的一部分。
rsyslogd 使用文本文件存储日志,而 systemd journald 使用二进制格式存储日志。
rsyslogd 支持更广泛的日志转发和处理选项,而 systemd journald 提供了更强大的查询和过滤功能。
rsyslogd 可以与其他日志处理工具集成,而 systemd journald 是 systemd 系统的默认日志管理工具。
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
# 最大占用空间 10G
SystemMaxUse=10G
# 单日志文件最大 200M
SystemMaxFileSize=200M
# 日志保存时间 2 周
MaxRetentionSec=2week
# 不将日志转发到 syslog
ForwardToSyslog=no
EOF
systemctl restart systemd-journald
9、升级系统内核为4.44
CentOS 7.x 系统自带的 3.10.x 内核存在一些 Bugs,导致运行的 Docker、Kubernetes 不稳定,例如: rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
# 安装完成后检查 /boot/grub2/grub.cfg 中对应内核 menuentry 中是否包含 initrd16 配置,如果没有,再安装 一次!
yum --enablerepo=elrepo-kernel install -y kernel-lt
# 设置开机从新内核启动
grub2-set-default 'CentOS Linux (4.4.189-1.el7.elrepo.x86_64) 7 (Core)'
grub2-set-default 'CentOS Linux (4.4.218-1.el7.elrepo.x86_64) 7 (Core)'
grub2-set-default 'CentOS Linux (4.4.219-1.el7.elrepo.x86_64) 7 (Core)'
查看所有可用内核
awk -F \' '$1=="menuentry " {print i++ " : " $2}' /etc/grub2.cfg
grub2-set-default 'CentOS Linux (4.4.248-1.el7.elrepo.x86_64) 7 (Core)'
二、 kube-proxy 开启ipvs的前置条件
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
(modprobe -- ip_vs:这个命令用于加载名为 ip_vs 的内核模块。ip_vs 模块是 Linux 内核中的一个模块,提供了 IP 虚拟服务器(IPVS)的功能,用于实现负载均衡和集群服务。
modprobe -- ip_vs_rr、modprobe -- ip_vs_wrr、modprobe -- ip_vs_sh:这些命令用于加载与 IPVS 相关的调度器模块。ip_vs_rr 是基于轮询的调度器,ip_vs_wrr 是基于加权轮询的调度器,ip_vs_sh 是基于散列的调度器。这些调度器用于决定负载均衡时数据包的路由方式。
modprobe -- nf_conntrack_ipv4:这个命令用于加载名为 nf_conntrack_ipv4 的内核模块。nf_conntrack_ipv4 模块是 Linux 内核中的一个模块,提供了 IPv4 连接跟踪的功能,用于跟踪和管理网络连接状态。)
chmod 755 /etc/sysconfig/modules/ipvs.modules && \bash /etc/sysconfig/modules/ipvs.modules &&\lsmod | grep -e ip_vs -e nf_conntrack_ipv4
(加载和配置一些 IPVS 相关的内核模块 。使用 lsmod 命令列出当前加载的内核模块,并通过 grep 命令进行过滤,只显示包含 ip_vs 或 nf_conntrack_ipv4 的模块信息。)
三、 安装docker软件
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager \
--add-repo \ http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum update -y && yum install -y docker-ce ##先更新系统中已安装的软件包到最新版本,然后安装 Docker 社区版。
此时k8s的版本可能已经更改,uname -r 查看是否之前设置的4.44,如果不是,重新设置默认版本,再重启。grub2-set-default 'CentOS Linux (4.4.189-1.el7.elrepo.x86_64) 7 (Core)' && reboot
systemctl start docker ##重启docker
systemctl enable docker ##设置开机自启
mkdir /etc/docker ## 创建 /etc/docker 目录
# 配置 daemon.
cat > /etc/docker/daemon.json <<EOF
{
"exec-opts": ["native.cgroupdriver=systemd"], ## 指定了 Docker 守护进程使用 systemd 作为 cgroup 驱动程序,用于管理容器的资源限制和隔离。
"log-driver": "json-file", ##指定了 Docker 容器的日志驱动程序为 json-file,即将容器的日志输出到文件中。
"log-opts": {
"max-size": "100m"
}
}
EOF
mkdir -p /etc/systemd/system/docker.service.d
# 重启docker服务
systemctl daemon-reload && systemctl restart docker && systemctl enable docker
四、 安装kubeadm(主从配置)
kubeadm是 Kubernetes 官方提供的一个命令行工具,用于在 Kubernetes 集群中初始化控制平面节点(Master 节点)和加入工作节点(Worker 节点)。
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
yum -y install kubeadm-1.15.1 kubectl-1.15.1 kubelet-1.15.1
systemctl enable kubelet.service
五、 初始化主节点
注意,此处可以先导入下载好的kubeadm 镜像(谷歌下载)
初始化 Kubernetes 集群,并根据指定的配置文件生成秘钥
kubeadm config print init-defaults > kubeadm-config.yaml
#更改kubeadm-config.yaml 文件
localAPIEndpoint:
advertiseAddress: 192.168.66.10 #更改为master的ip地址
kubernetesVersion: v1.15.1 #更改版本为当前版本
networking:
podSubnet: "10.244.0.0/16" #添加flannel 网络不然后面麻烦
serviceSubnet: 10.96.0.0/12
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
featureGates:
SupportIPVSProxyMode: true
mode: ipvs
做初始化并生成秘钥
kubeadm init --config=kubeadm-config.yaml --experimental-upload-certs | tee kubeadm-init.log
六、查看kubeadm-init.log \加入主节点以及其余工作节点
vim kubeadm-init.log (如果第5步前,没有导入镜像,通过下载方式获取镜像,时间会比较久。防止卡主,可以开个子终端,通过docker images 查看镜像是否有新增)
通过观察日志,发现需要做以下操作:
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 node
七、 部署网络,安装flannel
mkdir install-k8s
ls
mv kubeadm-init.log kubeadm-config.ymal install-k8s/
cd install-k8s
mkdir core
mv *core/
mkdir plugin
cd plugin/
mkdir flannel
cd flannel
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube- flannel.yml
kubectl create -f kube- flannel.yaml
kubectl get pod -n kube-system
备注:
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube- flannel.yml
kubectl apply -f 是在原有基础上升级
kubectl create -f 是直接新建
八、 加入其他节点
加入其他节点(在子节点执行 )(在主节点的日志文件里面找到命令):
kubeadmjoin192.168.66.10:6443--token abcdef.0123456789abcdef \--discovery-token-ca-cert-hash sha256:ed81ab06be57fa61df388ddce02b4a6d70d0e6a0be91b7b7382d8fd82970c964
kubectl get pod -n kube-system -o wide
kubectl get pod -n kube-system -w
mv install-k8s/ /usr/local/
rm -rf * install-k8s
2、配置私有仓库Harbor
Harbor 提供了一个安全、可靠的容器镜像仓库,帮助组织和团队有效地存储、管理和分发容器镜像,并提供了访问控制、安全扫描和审计等功能,以增强容器化应用的安全性和可管理性。
一、安装docker
在 CentOS 系统上安装 Docker 和 Docker Compose,并升级 Python pip 工具。
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
yum install docker-ce -y
yum install python-pip -y
pip install --upgrade pip
pip install docker-compose (单机编排工具)
二、更改vim /etc/docker/daemon.json 让其信任syuee.com 这个域名
注意,k8s机器也更改如下配置
{
"exec-opts": ["native.cgroupdriver=systemd"], "log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"registry-mirrors": ["https://f4573wwn.mirror.aliyuncs.com"],
"insecure-registries": ["https://hub.syuee.com"] ##认为它是安全的证书,省掉购买证书环节
}
yum -y install lrzsz ##lrzsz 是一个用于在终端中进行文件传输的工具,它支持通过串口、Telnet、SSH 等协议进行文件传输。
将docker-compose拖进服务器
mv docker-compose /usr/local/bin/
chmod a+x /usr/local/bin/ docker-compose
三、创建证书
openssl genrsa -des3 -out server.key 2048 #生成私钥输入两次密码(4位以上)
openssl req -new -key server.key -out server.csr #创建一个证书的请求
#第一个国家名:CN
#第二个省:SH
#第三个市:SH
#第四个组织:syuee
#第五个机构:syuee
#完全合规域名:hub.syuee.com
#管理员邮箱:sivan@syuee.com
#是否要改密码
cp server.key server.key.org #备份私钥
openssl rsa -in server.key.org -out server.key #去掉密码
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt #签名生成证书
mkdir /data/cert #创建/data/cert 目录 (存储ssl的目录)
chmod -R 777 /data/cert
四、上传harbor并解压
将habor-offline-installer-v1.2.0.tgz拖进服务器
tar -zvf habor-offline-installer-v1.2.0.tgz
mv harbor /usr/local/
更改配置文件vim /usr/local/harbor/harbor.cfg
cd /usr/local/harbor
vim harbor.cfg
更改hostname
hostname = hub.syuee.com
更改访问为https
ui_url_protocol = https
默认证书的位置是
ssl_cert = /data/cert/server.crt
ssl_cert_key = /data/cert/server.key
安装harbor
./install.sh
五、其他配置
配置hosts 解析(包含Harbor本机以及其他k8s服务器)
C:\Windows\System32\drivers\etc 的hosts 默认账号密码是 admin\Harbor12345
cat /etc/hosts
echo "192.168.66.100 hub.syuee.com" >> /etc/hosts
docker ps -a #查看运行的容器
启动后:https://hub.syuee.com 访问仓库
六、更改其他docker 指定仓库
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"insecure-registries": ["https://hub.syuee.com"]
}
七、验证
1、测试推送镜像到仓库
docker login https://hub.syuee.com #测试docker是否能访问仓库 admin\Harbor12345
docker pull nginx #下载一个镜像
docker tag nginx:latest hub.syuee.com/library/nginx:v1 #anHarbor标准,推送镜像需要 重新打标签
docker push hub.syuee.com/library/nginx:v1 #推送到仓库
hub.syuee.com/library/ingress-nginx-controller:v0.44.0
2、测试从k8s上拉取仓库中镜像
kubectl run nginx-deployment --image=hub.syuee.com/library/nginx:v1 --port=80 --replicas=1 #在 Kubernetes 集群中创建一个名为 nginx-deployment 的部署(Deployment)对象,并使用指定的镜像、端口和副本数量进行配置。从 Kubernetes 1.18 开始,kubectl run 命令的行为发生了变化。在新版本中,kubectl run 命令默认创建的是一个 Pod,而不是 Deployment。如果你使用的是较新的 Kubernetes 版本,可以使用 kubectl create deployment 命令来创建部署对象。
kubectl get deployment #获取当前 Kubernetes 集群中的部署(Deployment)对象的信息。包含就绪副本数、最新副本数和可用副本数等信息。
kubectl get rs #rs 是要获取信息的资源类型,表示 ReplicaSet 对象。包含期望副本数、当前副本数和可用副本数等信息
kubectl get pod
kubectl get pod -0 wide
3、k8s集群网络访问设置
kubectl scale --replicas=3 deployment/nginx-deployment #对pod扩容成3个副本
kubectl get svc #Service 是 Kubernetes 中用于提供网络访问和负载均衡的对象,用于将一组 Pod 暴露给集群内外的其他组件或用户。
问题1:怎么访问三个pod?传统通过nginx的upstream。k8s通过IPVS服务
kubectl expose deployment nginx-deployment --port=30000 --target-port=80 #在 Kubernetes 将创建一个 Service 对象,并将其与指定的 Deployment 对象关联起来。该 Service 对象将使用指定的端口号(这里是 30000)暴露服务,并将流量转发到与 Deployment 关联的 Pod 的指定端口号(这里是 80)。这样,通过访问 Service 的 IP 地址和端口号(例如,http://<Service-IP>:30000),可以访问到运行在 Deployment 中的 Pod 提供的服务。
ipvsadm -Ln | grep 10.97.154.59 #使用 ipvsadm 工具来列出 IPVS(IP Virtual Server)的配置。查找与指定 IP 地址相关的负载均衡规则或配置信息。通过执行该命令,可以查看与指定 IP 地址相关的负载均衡配置,例如目标服务器的 IP 地址、端口号、负载均衡算法等。
ipvsadm -Ln
问题2:怎么通过外网访问nginx-deployment ?10.97.154.59是内网地址,无法访问,但是可以 通过将svc的type改为NodePort类型,自动暴露端口 。注意,此时通过https://192.168.66.10 :31859 、https://192.168.66.20 :31859 、https://192.168.66.21 :31859 可以访问到NodePord节点
NodePort:
NodePort 是一种 Service 类型,它在每个节点上使用一个固定的端口(NodePort)来公开服务。
当创建一个 NodePort 类型的 Service 时,Kubernetes 集群会为该 Service 在每个节点上选择一个端口,并将该端口映射到该 Service 的目标端口(TargetPort)。
外部用户可以通过访问任何节点的 <NodeIP>:<NodePort> 来访问 Service,流量会被转发到 Service 底层的 Pod。
NodePort 类型的 Service 具有两个 IP 地址:一个是 Service 的 ClusterIP(集群内部 IP),用于在集群内部访问 Service;另一个是每个节点的 IP 地址,用于在集群外部访问 Service。
ClusterIP:
ClusterIP 是另一种 Service 类型,它为 Service 分配一个虚拟 IP 地址(ClusterIP)。
ClusterIP 类型的 Service 只能在集群内部访问,外部用户无法直接访问该 Service。
ClusterIP 类型的 Service 将流量转发到底层的 Pod,但不会公开给集群外部。
ClusterIP 类型的 Service 可以通过其他 Service 或 Ingress 对象来公开给集群外部。
在 Kubernetes 中,NodePort、Port 和 TargetPort 是 Service(服务)对象中用于定义端口映射和流量转发的不同属性。
NodePort:
NodePort 是 Service 对象的一个属性,用于指定在每个节点上公开服务的端口。
它是一个大于30000且小于32767的整数值,由 Kubernetes 集群自动分配。
外部用户可以通过访问任何节点的 <NodeIP>:<NodePort> 来访问 Service,流量会被转发到 Service 底层的 Pod。
NodePort 是一种公开服务给集群外部访问的方式。
Port:
Port 是 Service 对象的另一个属性,用于指定 Service 对象的端口号。
它定义了 Service 对象的入口端口,用于接收流量。
Port 是 Service 对象对外公开的端口,可以在集群内外使用该端口来访问 Service。
TargetPort:
TargetPort 是 Service 对象的另一个属性,用于指定将流量转发到 Service 底层 Pod 的端口。
它定义了 Service 对象将流量转发到哪个 Pod 的端口。
TargetPort 是 Service 对象与后端 Pod 之间的通信端口。
总结:
NodePort 是用于在每个节点上公开服务的端口,用于集群外部访问。
Port 是 Service 对象对外公开的端口,用于接收流量。
TargetPort 是 Service 对象将流量转发到后端 Pod 的端口。
外网------------------------Service --------------------------pod
NodePort ------------ Port ------------ TargetPort