安装环境
- 两台centos7操作系统的物理机。
- 能够访问网络。
- 本文中两台物理机分别为:k8s-master和k8s-node1,master的ip:192.168.3.5;node1的ip:192.168.3.6
安装前准备工作
注意准备工作在所有节点都要操作。
域名IP解析配置
- 设置域名
hostnamectl set-hostname k8s-master
hostnamectl set-hostname k8s-node1
- 配置域名IP
vim /etc/hosts
192.168.10.175 k8s-master
192.168.10.178 k8s-node1
- 分发/etc/hosts到各个其他节点
scp /etc/hosts root@k8s-node1:/etc/
配置yum安装软件源
yum安装源配置成阿里云的镜像仓库。这样在安装docker、k8s等依赖环境是能大大提高安装速度。本文中我们将原有的linux镜像源替换成阿里云的镜像源,替换之前先备份下
- 备份
#注意先安装wget在备份,后面要用到wget
yum install -y wget
mv /etc/yum.repos.d /etc/yum.repos.d.backup
- 新建空的repository
mkdir /etc/yum.repos.d
- 下载阿里repository
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
- 重建缓存
#清除缓存
yum clean all
#重建缓存
yum makecache
安装依赖环境
yum install -y conntrack ntpdate ntp ipvsadm ipset jq iptables curl sysstat libseccomp wget vim net-tools device-mapper-persistent-data lvm2
设置防火墙配置iptables
- 先停止并且禁用firewalld。安装过程中先不用防火墙,安装完成后可以配置防火墙放开需要的端口
systemctl stop firewalld && systemctl disable firewalld
- 通过yum安装iptables且设置成开机启动
yum -y install iptables-services && systemctl start iptables && systemctl enable iptables && iptables -F && service iptables save
关闭 selinux和swap
# 关闭swap
swapoff -a && sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
#关闭selinux
setenforce 0 && sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
调整K8S内核参数
mkdir -p /etc/sysctl.d/kubernetes
cat > /etc/sysctl.d/kubernetes/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
net.netfilter.nf_conntrack_max=2310720
EOF
注意内核参数配置文件在所有节点上都要操作,本章节为环境准备,所有节点上都要操作的。内核配置文件同样可以通过scp分发到其他节点。
scp /etc/sysctl.d/kubernetes/kubernetes.conf root@k8s-node1:/etc/sysctl.d/kubernetes/
调整系统时区
# 设置系统时区为中国/上海
timedatectl set-timezone Asia/Shanghai
# 将当前的 UTC 时间写入硬件时钟
timedatectl set-local-rtc 0
# 重启依赖于系统时间的服务
systemctl restart rsyslog
systemctl restart crond
注意所有节点上都要执行
关闭系统不需要服务
systemctl stop postfix && systemctl disable postfix
置 rsyslogd 和 systemd journald
# 持久化保存日志的目录
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
日志转发,如果想提供系统性能可以不转发,但是不转发日志后,通过docker logs 等命令查不到容器的日志。此问题有待测试。
升级linux系统内核
参考另一篇博文
内核升级后需要重启检查下当前内核版本。linux内核会影响驱动的安装,比如nvidia的显卡驱动。
kube-proxy开启ipvs的前置条件
注意下以下echo "1" >/proc/sys/net/bridge/bridge-nf-call-iptables 命令,在尚硅谷视频教没有涉及,但是如果不执行,在后面部署flannel 以及join节点时会提示这个错误。也可以在后续出现提示后再执行该命令。
#修改bridge-nf-call-iptables值
echo "1" >/proc/sys/net/bridge/bridge-nf-call-iptables
modprobe br_netfilter
#新建ipvs.modules 配置文件
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
docker安装
因为k8s主要就是管理docker的,所以要安装k8s需要在每一台节点上都安装docker。
安装docker依赖环境
yum install -y yum-utils
设置Docker源
这里一定要设置docker源为阿里镜像源,不然安装过程会非常慢。默认国外的镜像。
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum-config-manager命令是组件包yum-utils提供的。
安装Docker CE
#查看版本
yum list docker-ce --showduplicates | sort -r
#指定版本安装
yum install -y docker-ce-18.09.6 docker-ce-cli-18.09.6 containerd.io
# 安装最新版本
yum install -y docker-ce docker-ce-cli containerd.io
-
注意:不要安装最新版本,本文安装一开始选择的时最新docker-ce版本。后续再安装k8s并且再添加节点时,会提示当前k8s支持的最新版本是18.09.6。
-
注意:docker版本更新很快,本文安装时docker-ce最新版本是19.03.5
-
注意:强烈建议指定版本安装,并且要同时指定 docker-ce 和docker-ce-cli,一个server端和一个client端,如果这两个版本不匹配很容易出问题
关于docker的介绍请参见博文docker概念介绍
配置 daemon以及开机自启
cat > /etc/docker/daemon.json <<EOF
{
"registry-mirrors": [
"https://m5gxo8hk.mirror.aliyuncs.com"
],
"exec-opts": [
"native.cgroupdriver=systemd"
],
"log-driver": "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
安装k8s
该章节所有节点都需要执行
配置kubernetes.repo 源
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
安装kubeadm、kubectl、kubelet
#安装最新版本
yum -y install kubeadm kubectl kubelet
#设置开机自启
systemctl enable kubelet.service
#指定版本安装,本文默认安装最新版本
yum install -y kubelet-1.16.3-0 kubeadm-1.16.3-0 kubectl-1.16.3-0
#安装完成后查看版本
kubectl version
-
注意:同样这里强烈推荐指定版本安装,不要安装最新版本
-
注意:本文中安装的版本是1.16.3,后续很多操作都和版本有关系,所以最好按照本文中版本安装,版本不同后续操作可能会有问题,具体需要查看日志
以上过程中,所有操作都需要在所有节点上执行。并且如果我们的场景是添加新节点,只要在新节点上按照以上步骤操作,然后执行添加节点的命令即可,添加新节点前提是集群环境已经搭建完成
添加新节点请参考博文k8s添加节点
master节点安装
本章节主要简介master节点的安装过程,本章节只需要在master节点上操作即可。
初始化master节点
之前内容中我们已经通过yum安装了kubeadm、kubectl、kubelet三大组件。接下来我们就是要通过kubeadm来初始化master节点,然后陆续通过kubectl来部署网络、dashboard等pod组件。
- 提前下载镜像。初始化master节点时,docker会从k8s.grc.io仓库中下载镜像,所以我们通过阿里云提前下载镜像然后重命名镜像名称。因为镜像有点多,所以通过以下脚本来实现镜像的下载。
#先按照k8s版本生成镜像下载命令
cat <<EOF > image.sh
#!/bin/bash
url=registry.cn-hangzhou.aliyuncs.com/google_containers
version=v1.16.3
images=(`kubeadm config images list --kubernetes-version=$version|awk -F '/' '{print $2}'`)
for imagename in ${images[@]} ; do
docker pull $url/$imagename
docker tag $url/$imagename k8s.gcr.io/$imagename
docker rmi -f $url/$imagename
done
EOF
#执行下载脚本
sh ./image.sh
注意,该脚本再各个 节点都执行以下。避免其他节点也需要用到这些镜像
- 通过以下命令生成初始化master节点配置文件
kubeadm config print init-defaults > kubeadm-config.yaml
- 修改kubeadm-config.yaml配置文件
localAPIEndpoint:
advertiseAddress: 192.168.3.
kubernetesVersion: v1.16.3
networking:
podSubnet: "10.244.0.0/16"
serviceSubnet: 10.96.0.0/12
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
featureGates:
SupportIPVSProxyMode: true
mode: ipvs
主要修改advertiseAddress、kubernetesVersion、podSubnet、serviceSubnet。修改内容说明:
advertiseAddress修改成自己master节点的IP
kubernetesVersion修改成安装的k8s版本
添加一个podSubnet,内容照抄
添加apiVersion,内容照抄
- 执行命令完成初始化
kubeadm init --config=kubeadm-config.yaml --upload-certs | tee kubeadm-init.log
以上命令中kubeadm-config.yaml中涉及到镜像信息,命令的镜像源为国外网站,不翻墙的话拉不下来,解决方式可以在docker安装环节中设置镜像加速服务。或者通过以下命令来完成初始化
kubeadm init \
--apiserver-advertise-address=192.168.3.5 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.16.3 \
--service-cidr=10.1.0.0/16 \
--pod-network-cidr=10.244.0.0/16 \
--upload-certs | tee kubeadm-init.log
注意以上命令的参数,其实我们也可以将kubeadm-config.yaml 中的镜像地址改成 registry.aliyuncs.com/google_containers。这里最好还是直接执行上述中的命令。其他方式并没有真正实验过。
本文中提供一个kubeadm-config.yaml
- 初始化完成后需要按照初始化后的日志提示执行以下命令
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
- 通过命令查看当前node节点状态
kubectl get nodes
刚初始化完成的master节点状态时notready。因为k8s默认需要一个扁平化网络flannel节点状态才会显示ready。
小提示: 如果kubeamd init初始化失败可以执行以下命令然后重新初始化。
kubeadm reset
部署网络flannel
- 先下载kube-flannel的yaml部署文件
wget https://github.com/coreos/flannel/blob/master/Documentation/kube-flannel.yml
注意: 以上命令中获取到的文件有可能是html文件,这是我们可以直接去github官网下载。本文中提供一个文件(也是从官网中下载的)kube-flannel.yml。并且在部署flannel时物理机一定要配置网关哦,也就是GATEWAY.
- 应用以下kube-flannel.yml文件,该过程中会下载docker镜像。我们的docker镜像已经配置了阿里云镜像仓库加速地址。
kubectl apply -f kube-flannel.yml
- flannel 部署好,要查看所有pod是不是处于running状态,切查看当前master node 是不是ready状态。当前flannel默认的namespace是再kube-system下面。
kubectl get pod -n kube-system
Flannel部署完成后,master节点状态会变成ready状态。
部署Dashboard
- 同样和flannel一样,我们需要先获取 dashboard的yaml文件
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta6/aio/deploy/recommended.yaml
- 修改recommended.yaml文件内容(vi recommended.yaml)
---
#增加直接访问端口
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
type: NodePort
ports:
- port: 443
targetPort: 8443
nodePort: 30030
selector:
k8s-app: kubernetes-dashboard
---
#因为自动生成的证书很多浏览器无法使用,所以我们自己创建,注释掉kubernetes-dashboard-certs对象声明
#apiVersion: v1
#kind: Secret
#metadata:
# labels:
# k8s-app: kubernetes-dashboard
# name: kubernetes-dashboard-certs
# namespace: kubernetes-dashboard
#type: Opaque
---
这里提供一个已经修改好的yaml文件recommended.yaml
- 创建证书
上面说过,dashboard默认的证书文件谷歌浏览器不识别,所以这里我们需要自己创建证书。
mkdir dashboard-certs
cd dashboard-certs/
#创建命名空间
kubectl create namespace kubernetes-dashboard
# 创建key文件
openssl genrsa -out dashboard.key 2048
#证书请求
openssl req -days 36000 -new -out dashboard.csr -key dashboard.key -subj '/CN=dashboard-cert'
#自签证书
openssl x509 -req -in dashboard.csr -signkey dashboard.key -out dashboard.crt
#创建kubernetes-dashboard-certs对象
kubectl create secret generic kubernetes-dashboard-certs --from-file=dashboard.key --from-file=dashboard.crt -n kubernetes-dashboard
- 安装Dashboard
kubectl create -f ./recommended.yaml
#检查结果
kubectl get pods -A -o wide
kubectl get service -n kubernetes-dashboard -o wide
- 创建dashboard管理员ServiceAccount
只有创建管理员权限,登录后才能看到资源。
#新建yaml文件
vi dashboard-admin.yaml
#文件内容如下
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: kubernetes-dashboard
name: dashboard-admin
namespace: kubernetes-dashboard
#保存退出后执行
kubectl create -f dashboard-admin.yaml
- 用户分配权限
#创建yaml文件
vi dashboard-admin-bind-cluster-role.yaml
#文件内容如下
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: dashboard-admin-bind-cluster-role
labels:
k8s-app: kubernetes-dashboard
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: dashboard-admin
namespace: kubernetes-dashboard
#保存退出后执行
kubectl create -f dashboard-admin-bind-cluster-role.yaml
以上所有安装好后master节点就安装好了。此时我们已经可以登录dashboard管理k8s集群了。
登录dashboard
- 查看并复制用户Token
kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep dashboard-admin | awk '{print $1}')
复制得到token值。
输入token登录即可
如果没有其他节点,登录后只能看到master节点。接下来我们可以通过kubeadm来添加node节点。注意node节点必须完成本文中环境准备、docker安装、k8s安装
添加节点
添加节点请参考博文添加节点
爬坑指南
解决pod ping cluster IP
解决该问题首先要指导k8s proxy路由代理机制。最新版本的k8s proxy路由模式是ipvs 。本文在安装的k8s的时候好像没有介绍这一块。但是安装了iptables 服务。应该是文章内容比较老所以出现问题。iptables 是以前老版本使用的。详细请参考【调整内核参数,对于 K8S】章节。
修改kube-proxy configMap
kubectl edit cm kube-proxy -n kube-system
可以使用命令修改configMap
也可以在dashboard上通过浏览器直接修改
解决pod wget cluster IP:PORT
这问题的情况是首先我已经修改了kube proxy代理模式为ipvs。在pod里能够ping通service的cluster ip,但是无法访问service代理的服务。原因是虽然我的ipvs路由表里已经有了路由的端口映射关系, 但是我的物理机节点没有开启路由转发功能
cat <<EOF > /etc/sysctl.d/k8s.conf
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF