角色 | 实验环境 | 生产环境 | 操作系统 |
master | cpu/内存:2 Core/2G | cpu/内存:2 Core/4G | linux 内核4.4+ |
node | cpu/内存:1 Core/2G | cpu/内存:4 Core/16G | linux 内核4.4+ |
备注 | Node:应根据需要运行的容器数量进行配置; 以下环境配置OS基于 Linux for ubuntu-server 20.04 Linux Kernel =》5.4.0-47-generic 查看linux内核版本=》在命令行中查看Linux内核版本的3种方法_Linux教程_Linux公社-Linux系统门户网站 |
||
说明 | 以上为建议配置,实际安装过程中,Master必须2 core 及以上(否则安装失败,切记),Node可以采用1 core。 |
主机 | 配置 | 组件 | ip |
k8s-master01 | cpu/内存:2 Core/2G 硬盘:40GB 网络模式:桥接 |
kube-apiserver, kube-controller-manager,kube-scheduler, etcd |
192.168.0.168 |
k8s-node01 | cpu/内存:2 Core/2G 硬盘:40GB 网络模式:桥接 |
kubelet, kube-proxy, docker etcd |
192.168.0.116 |
k8s-node02 | cpu/内存:2 Core/2G 硬盘:40GB 网络模式:桥接 |
kubelet, kube-proxy, docker etcd |
192.168.0.154 |
备注 | linux 版本:ubuntu-20.04-live-server-amd64.iso kubernetes 版本:v1.19.1 docker 版本:v19.03.8-ce vm 版本:VMware Workstation Pro 15.6 客户端使用 xshell6 连接到 vm 中 linux 系统方便安装配置; |
||
说明 | 以上配置为3节点主机的单Master架构的最小规模集群配置,配置环境均在VM中部署安装,宿主机固定静态IP,保障vm中linux系统的网络在同一网段,使用桥接模式,宿主机和vm系统之间能相互通信,vm中系统能正常访问外网; 生产环境建议扩展多 Master 架构集群部署,node节点根据部署容器数量预估配置; |
Ubuntu20.04一般都默认安装了UFW(Uncomplicated Firewall)防火墙服务,它是一款轻量化的工具,主要用于对输入输出的流量进行监控。而Kubernetes的Master与工作Node之间会有大量的网络通信,安全的做法是在防火墙上配置Kbernetes各组件(api-server、kubelet等等)需要相互通信的端口号。在安全的内部网络环境中可以关闭防火墙服务。
# 查看防火墙状态
$ sudo ufw status verbose
# 关闭ubuntu的防火墙
$ sudo ufw disable
ubuntu关闭和开启防火墙
ubuntu20.04防火墙设置简易教程(小白)
安全增强型 Linux(Security-Enhanced Linux)简称 SELinux,它是一个 Linux 内核模块,也是 Linux 的一个安全子系统。
SELinux 主要由美国国家安全局开发。2.6 及以上版本的 Linux 内核都已经集成了 SELinux 模块。
SELinux 的结构及配置非常复杂,而且有大量概念性的东西,要学精难度较大。很多 Linux 系统管理员嫌麻烦都把 SELinux 关闭了。
关闭SELinux的两种方法
1. 永久方法 – 需要重启服务器
修改 /etc/selinux/config 文件中设置 SELINUX=disabled,然后重启服务器。
2. 临时方法 – 设置系统参数
使用命令 setenforce 0
附:
setenforce 1 设置 SELinux 成为 enforcing 模式
setenforce 0 设置 SELinux 成为 permissive 模式
# 安装 selinux-utils
$ apt install selinux-utils
# 查看 selinux 是否关闭
$ getenforce
# 临时
$ setenforce 0
# 永久
$ sed -i 's/enforcing/disabled/' /etc/selinux/config
这个 swap 其实可以类比成 windows 上的虚拟内存,它可以让服务器在内存吃满的情况下可以保持低效运行,而不是直接卡死。但是 k8s 的较新版本都要求关闭 swap,修改 /etc/fstab
文件:
# 临时
$ sudo swapoff -a
# 永久,修改/etc/fstab,注释掉swap那行,持久化生效
$ sudo vi /etc/fstab
# 查看主机名称
$ hostname
# 设置主机名称
$ hostnamectl set-hostname
hosts 文件的作用相当如 DNS(Domain Name System),提供 IP 地址到 hostname 的映射。早期的互联网计算机少,单机hosts文件里足够存放所有联网计算机。不过随着互联网的发展,这就远远不够了。于是就出现了分布式的DNS系统。由DNS服务器来提供类似的IP地址到域名的对应。具体可以 man hosts。/etc/hosts 中包含了IP地址和主机名之间的映射,还包括主机名的别名。
hosts 文件的配置格式是: IP FQDN alias,其中全域名(FQDN,Fully Qualified Domain Name)是指主机名加上全路径,全路径中列出了序列中所有域成员。全域名可以从逻辑上准确地表示出主机在什么地方,也可以说全域名是主机名的一种完全表示形式。从全域名中包含的信息可以看出主机在域名树中的位置。
Linux 系统在向 DNS 服务器发出域名解析请求之前会查询 /etc/hosts 文件,如果里面有相应的记录,就会使用 hosts 里面的记录。
此处 hosts 类似 DNS(Domain Name System),DNS可以降低延迟,但是不能提高上下行网速。
$ cat >> /etc/hosts << EOF
172.26.16.100 k8s-master01
172.26.16.101 k8s-node01
172.26.16.102 k8s-node02
EOF
注意:此处添加 hosts 防止重启 linux 系统后,IP 无效,可以事先根据规划的网段设置好静态IP地址,操作如下:Ubuntu 18.04配置静态IP地址
使用 Netplan(新一代网络配置工具)工具配置网络
1. 备份系统默认 /etc/netplan/*.yaml 文件
$ sudo cp /etc/netplan/00-installer-config.yaml /etc/netplan/00-installer-config.yaml.bak
2. 编写 /etc/netplan/*.yaml 文件
network:
version: 2
renderer: networkd
ethernets:
eth0: #配置的网卡名称
dhcp4: false #dhcp4关闭
dhcp6: false #dhcp6关闭
addresses: [172.26.16.100/16] #设置本机IP及掩码
gateway4: 172.26.16.1 #设置网关
nameservers:
addresses: [114.114.114.114, 8.8.8.8] #设置DNS
DNS 可以配置多个,配置列表见附件。
IP 地址段和子网掩码对照表 =》
3. 执行 apply 命令,使 yaml 配置生效
$ netplan apply -f 00-installer-config.yaml
附:国内知名公共DNS服务器IP
每个宿主机上都要确保时区和时间是正确的。如果时区不正确,请使用下面的命令来修改:
$ sudo timedatectl set-timezone Asia/Shanghai
#修改后,如果想使得系统日志的时间戳也立即生效,则:
$ sudo systemctl restart rsyslog
(Ubuntu如何同步网络时间)装完Ubuntu设置完时间,重启总是恢复设置前的时间。
解决方法:
# 1.安装ntpdate工具
$ sudo apt install ntpdate -y
# 2.将系统时间与网络同步
$ ntpdate cn.pool.ntp.org
# 3.将时间写入硬件
$ hwclock --systohc
# 4.查看时间是否已同步
$ date
$ sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target
先确认 Linux 内核加载了 br_netfilter 模块:
$ lsmod | grep br_netfilter
确保 sysctl 配置中 net.bridge.bridge-nf-call-iptables 的值设置为了 1。
在Ubuntu 20.04 Server上,这个值就是1。如果你的系统上不一致,使用下面的命令来修改:
$ 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 # 生效
$ cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
$ sudo sysctl --system # 生效
因为 K8s 集群即将部署的是 calico 网络插件,而 calico 需要这个内核参数是0或者1,但是Ubuntu20.04 上默认是2,这样就会导致 calico 插件报下面的错误(这是个fatal级别的error):
int_dataplane.go 1035: Kernel's RPF check is set to 'loose'. \
This would allow endpoints to spoof their IP address. \
Calico requires net.ipv4.conf.all.rp_filter to be set to 0 or 1. \
If you require loose RPF and you are not concerned about spoofing, \
this check can be disabled by setting the IgnoreLooseRPF configuration parameter to 'true'.
使用下面的命令来修改这个参数的值:
# 修改/etc/sysctl.d/10-network-security.conf
$ sudo vi /etc/sysctl.d/10-network-security.conf
# 将下面两个参数的值从2修改为1
$ net.ipv4.conf.default.rp_filter=1
$ net.ipv4.conf.all.rp_filter=1
# 然后使之生效
$ sudo sysctl --system
$ shutdown -r now #重启系统
Kubernetes 在1.20.x 版本以前默认 CRI/Container Runtime Interface(容器运行时)为 Docker,因此此处先安装 Docker;
关于 CRI 的一些实现:
其它的 CRI 实现,这里就不一一介绍了,更多详细信息自行查阅资料。
注:Kubernetes 官方发布公告,宣布自 v1.20 起放弃对 Docker 的支持,届时用户将收到 Docker 弃用警告,并需要改用其他容器运行时。目前 k8s 最新版默认容器运行时是 CRI-containerd。
目前Ubuntu 20.04上没有docker官方提供的安装包,但是Ubuntu有,使用下面的命令来安装Docker;
1. apt 方式安装 docker
# 安装 Docker
$ sudo apt update && sudo apt install docker.io
# 启动 Docker,并设置为开机启动
$ sudo systemctl start docker && systemctl enable docker
注意:apt 方式安装 docker, daemon.json 文件的位置在 /etc/docker/ 文件下面。
2. snap 方式安装 docker
# 安装 docker
$ sudo snap install docker
# 启动 docker
$ sudo snap start docker
注意:snap 方式安装 docker,daemon.json 文件的位置在 /var/snap/docker/*/config/ 文件下面。
参考:Ubuntu 20.04 以 snap 的方式安装 Docker
$ docker -v # 查看docker版本
$ cat > /etc/docker/daemon.json << EOF
{
"registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"]
}
EOF
$ systemctl restart docker
$ docker info
国内从 Docker Hub 拉取镜像有时会遇到困难,此时可以配置镜像加速器。Docker 官方和国内很多云服务商都提供了国内加速器服务,例如:
#第一步:备份源文件:
$ sudo cp /etc/apt/sources.list /etc/apt/sources.list.backup
#第二步:编辑/etc/apt/sources.list文件
#在文件最前面添加以下条目(操作前请做好相应备份):
$ vi /etc/apt/sources.list
# 阿里云 apt 源
# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
#deb-src http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
#deb-src http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
#deb-src http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
#deb-src http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
# 预发布软件源,不建议启用
#deb http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse
#deb-src http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse
#第三步:执行更新命令:
$ sudo apt-get update
$ sudo apt-get upgrade
其中 3.4 参考如下:
#1.查看 docker 服务是否开机启动
$ sudo systemctl list-unit-files | grep enable|grep docker
snap-docker-1125.mount enabled
snap.docker.dockerd.service enabled
#2.关闭 docker 开机自启动
$ systemctl disable snap.docker.dockerd.service
Removed /etc/systemd/system/multi-user.target.wants/snap.docker.dockerd.service.
#3.开启 docker 开机自启动
$ systemctl enable snap.docker.dockerd.service
#4.关闭 docker 服务
$ systemctl stop snap.docker.dockerd.service
#5.启动 docker 服务
$ systemctl start snap.docker.dockerd.service
#6.查看 docker 服务是否启动
$ sudo systemctl list-units --type=service|grep docker
snap.docker.dockerd.service loaded active running Service for snap application docker.dockerd
注意:以上操作(除开2.4、2.5)均在所有节点执行;
以下的操作只在master宿主机上执行,适合中国大陆地区使用(因为弃用谷歌的源和repo,转而使用阿里云的镜像):
$ sudo apt update && sudo apt install -y ca-certificates curl software-properties-common apt-transport-https curl
$ curl -s https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add -
$ sudo tee /etc/apt/sources.list.d/kubernetes.list <
注意:在所有节点均安装 kubelet、 kubeadm 和 kubectl。
注意,这里使用了阿里云的镜像,然后使用了非默认的CIDR(一定要和宿主机的局域网的CIDR不一样!)
=》4.1.2.1 命令初始化
$ kubeadm init \
--apiserver-advertise-address=172.26.16.100 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.18.0 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16 \
--ignore-preflight-errors=all
# 或者 --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers
命令参数说明:
=》4.1.2.2 yaml 配置文件引导初始化
# 编辑配置文件
$ vi kubeadm.conf
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v1.18.0
imageRepository: registry.aliyuncs.com/google_containers
networking:
podSubnet: 10.244.0.0/16
serviceSubnet: 10.96.0.0/12
#执行并应用配置文件
$ kubeadm init --config kubeadm.conf --ignore-preflight-errors=all
上面的命令执行成功后,会输出一条和 kubeadm join 相关的命令,后面加入worker node 的时候要使用。
输出其他节点加入 master 的命令:
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
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 192.168.0.168:6443 --token cm1xr0.frcfjgtg0q4we4z0 \
--discovery-token-ca-cert-hash sha256:80705f99840e6c80b46e5f1dead4f15a843f90514d3e9d2d449694c2a5eff6e1
拷贝kubectl使用的连接k8s认证文件到默认路径,给自己的非sudo的常规身份拷贝一个token,这样就可以执行kubectl命令了:
# 切换到非管理员账户
$ su chait
# 最后拷贝 kubectl 工具用的 kubeconfig 到默认路径下
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.18.0
在每个 node/worker 宿主机上,执行上面初始化 master 最后输出的命令,如下所示:
kubeadm join 192.168.0.168:6443 --token cm1xr0.frcfjgtg0q4we4z0 \
--discovery-token-ca-cert-hash sha256:80705f99840e6c80b46e5f1dead4f15a843f90514d3e9d2d449694c2a5eff6e1
接下来在 node/worker 节点输入命令=》【kubectl get pods】,结果出现如下错误:
The connection to the server localhost:8080 was refused - did you specify the right host or port?
出现这个问题的原因是kubectl命令需要使用 kubernetes-admin 来运行,解决方法如下,将 Master 节点中的【/etc/kubernetes/admin.conf】文件拷贝到 worker 节点相同目录下,然后配置环境变量:
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
source ~/.bash_profile # 立即生效
再次输入命令【kubectl get pods --all-namespaces】查看所有pod的命名空间,显示如下:
默认 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/^.* //'
80705f99840e6c80b46e5f1dead4f15a843f90514d3e9d2d449694c2a5eff6e1
$ kubeadm join 192.168.31.61:6443 --token nuja6n.o3jrhsffiqs9swnu --discovery-token-ca-cert-hash sha256:80705f99840e6c80b46e5f1dead4f15a843f90514d3e9d2d449694c2a5eff6e1
命令:kubeadm token create --print-join-command
参考地址 =》kubeadm join | Kubernetes
=》 Quickstart for Calico on Kubernetes
下载 calico 的 k8s yaml 文件
# 下载 https://docs.projectcalico.org/v3.11/manifests/calico.yaml
sudo wget https://docs.projectcalico.org/v3.11/manifests/calico.yaml
# 修改CALICO_IPV4POOL_CIDR
root@k8s-master01:/# vim calico.yaml
# 通过文件名或控制台输入,对资源进行配置。
root@k8s-master01:/# kubectl apply -f calico.yaml
下载完后还需要修改里面配置项:
修改里面的 CALICO_IPV4POOL_CIDR 的值来避免和宿主机所在的局域网段冲突(把原始的192.168.0.0/16 修改成了172.16.0.0/16):
修改完后应用清单:
等待所有的 pod 都 ready 就绪。
在Kubernetes集群中创建一个pod,验证是否正常运行:
$ kubectl create deployment nginx --image=nginx
$ kubectl expose deployment nginx --port=80 --type=NodePort
$ kubectl get pod,svc
访问地址:http://NodeIP:Port
kubernetes/dashboard =》https://github.com/kubernetes/dashboard
执行命令:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.4/aio/deploy/recommended.yaml
以上方式启动 dashboard 访问会不太方便,只能在集群内部(cluster-ip)访问,可修改 yaml 中的 service 暴露端口方式为 NodePort 类型,即可直接在浏览器中访问;
$ vi recommended.yaml
...
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
ports:
- port: 17030
targetPort: 8443
type: NodePort
externalIPs:
- 192.168.0.168
selector:
k8s-app: kubernetes-dashboard
...
$ kubectl apply -f recommended.yaml
$ kubectl get pods -n kubernetes-dashboard
NAME READY STATUS RESTARTS AGE
dashboard-metrics-scraper-6b4884c9d5-gl8nr 1/1 Running 0 13m
kubernetes-dashboard-7f99b75bf4-89cds 1/1 Running 0 13m
执行上面命令可能出现网络原因访问不起,可以 github 直接下载相应 yaml 文件设置;
在需要部署的节点中安装文件传输工具:
$ sudo apt install lrzsz # 安装 rz 工具
$ rz # 选择上传的文件
此时查看当前列表=》【ls】
此处 dashboard 本人是安装在 master 节点,安装信息如下:
访问地址:https://NodeIP:30001
创建 service account 并绑定默认 cluster-admin 管理员集群角色:
# 创建用户
$ kubectl create serviceaccount dashboard-admin -n kube-system
# 用户授权
$ kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
# 获取用户Token
$ kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')
使用输出的 token 登录 Dashboard。
此处我们使用 NGINX ingress controller 方式安装,更多的安装方式查看=》Ingress Controllers | Kubernetes ;K8s官方支持和维护的是GCE和NGINX两种controller,执行如下命令:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-0.32.0/deploy/static/provider/baremetal/deploy.yaml
上面方式可能存在网络访问失败的情况,此处安装的是【ingress-nginx】版本【v0.30.0】,ingress-controller.yaml 文件已经下载好,rz 上传到 worker 节点,如下所示:
最后我们来查看下单 Master 架构的3节点集群情况, 显示信息如下:
启动成功后,可在内网节点的浏览器中访问 =》
http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/
vmware 虚拟化节点访问 =》
curl http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/
如果Kubernetes API服务器是公开的并且可从外部访问,就可以用API Server来访问 =》
https://:/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/
查看yaml文件对应的镜像版本
cat kubernetes-dashboard.yaml|grep kubernetes-dashboard
有两种登录模式:Kubeconfig 和 Token;
此处我使用的是 Token 方式登陆,获取 Token =》 输入以下命令来创建用户 token,利用 token 来登录 dashboard:
kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')
参考链接: