上一节, 我们介绍了 kubernetes 的一些基本概念, 这一节将带领大家一起搭建一个 k8s 集群, 在实践中领悟 k8s 的各个核心概念和 k8s 架构. 还是那句话, k8s 是一个生产级容器编排工具, 所以, 实践是必不可少的, 没有实践, 看的再多只是自己认为自己会了, 上手都出都是问题, 所以, 一起来搭建吧…哈哈, 我可不是唬你哦…

2.2 k8s 集群规划

2.2.1 平台规划

  • 一主多从(测试环境)

Kubesphere DNS配置_kubernetes

  • 多主多从(生产环境)

Kubesphere DNS配置_分布式_02

实际上, k8s 也支持单机部署, 但是一般不用, 一般只用于体验 k8s 的功能

2.2.2 硬件配置

  • 一台或多台机器,操作系统 CentOS7.x-86_x64
  • 硬件配置:2GB或更多RAM,2个CPU或更多CPU,硬盘30GB或更多
  • 可以访问外网,需要拉取镜像,如果服务器不能上网,需要提前下载镜像并导入节点
  • 禁止swap分区

Kubesphere DNS配置_k8s集群_03

Kubesphere DNS配置_分布式_04

**如果是虚拟机环境, 则要求更高, 一主多从集群环境在 16G 内存 + SSD 的 MacBook Pro 上偶尔已经可以感受到卡顿 **

2.2.3 搭建集群的方式

  • kubeadm

简单, 快速, 组件自动安装

  • 二进制包

过程繁琐, 所有组件都需要自行安装, 并且底层配置复杂, 容易出错且不易排查, 只适用于底层原理学习阶段

2.3 kubeadm 的方式搭建 k8s 集群

2.3.1 环境准备

Kubesphere DNS配置_docker_05

角色

IP

master1

192.168.3.18

node1

192.168.3.19

node2

192.168.3.20

这里帅帅已经提前准备好了三台虚拟机, 不会安装虚拟机的同学可以参考帅帅前一篇文章 Virtual Box 安装虚拟机及网络配置

2.3.1.1关闭防火墙
# centos
systemctl stop firewalld
systemctl disable firewalld

# Ubuntu
ufw disable
2.3.1.2 关闭selinux
# centos
sed -i 's/enforcing/disabled/' /etc/selinux/config  # 永久
setenforce 0  # 临时

# Ubuntu 默认没有 selinux
2.3.1.3 关闭swap
sudo swapoff -a  # 临时
sudo sed -ri 's/.*swap.*/#&/' /etc/fstab    # 永久

# 查看 swap 分区是否开启, 输出为空则表示未开启
swapon --show
2.3.1.4 根据规划设置主机名

这里主要是为了业务更加清晰设置主机名可以更好的区分 master, node 节点. 是否需要设置大家根据自己情况, 这一步并不是必须的, 由于我们创建虚拟机的时候已经命名好了, 这里就跳过设置.

# 设置
hostnamectl set-hostname <hostname>

# 查看
hostname
2.3.1.5 在 master 添加 hosts
cat >> /etc/hosts << EOF
192.168.3.18 master1
192.168.3.19 node1
192.168.3.20 node2
EOF

如果文件是只读模式, 则可以 copy 出来编辑好再 copy 回去替换

master1@master1:~$ pwd
/home/master1
master1@master1:~$ cp /etc/hosts ./hosts
master1@master1:~$ sudo cat >> ./hosts << EOF
192.168.3.18 master1
192.168.3.19 node1
192.168.3.20 node2
EOF

master1@master1:~$
master1@master1:~$ vi ./hosts
master1@master1:~$ cp ./hosts /etc/hosts
hosts        hosts.allow  hosts.deny
master1@master1:~$ cp ./hosts /etc/hosts
hosts        hosts.allow  hosts.deny
master1@master1:~$ cp ./hosts /etc/hosts
cp: cannot create regular file '/etc/hosts': Permission denied
master1@master1:~$ sudo cp ./hosts /etc/hosts

master1@master1:~$ cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 master1

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.3.18 master1
192.168.3.19 node1
192.168.3.20 node2
master1@master1:~$
2.3.1.6 内核开启 ipv4 转发

什么是ipv4转发:出于安全考虑,Linux系统默认是禁止数据包转发的。转发即当主机拥有多于一块的网卡时,其中一块收到数据包,根据数据包的目的ip地址将数据包发往本机另一块网卡,该网卡根据路由表继续发送数据包。这通常是路由器所要实现的功能。
kube-proxy的ipvs模式和calico(都涉及路由转发)都需要主机开启ipv4转发。
另外,不使用k8s,即使只使用docker的时候,以下两种情况也依赖ipv4转发:
*当同一主机上的两个跨bridge(跨bridge相当于跨网段,跨网络需要路由)的容器互访

  • 从容器内访问外部
$ sudo vim /etc/sysctl.conf
net.ipv4.ip_forward = 1             #开启ipv4转发,允许内置路由

sudo sysctl -p
2.3.1.7 将桥接的IPv4流量传递到iptables的链
sudo cat > ./k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

sudo cp ./k8s.conf /etc/sysctl.d/k8s.conf

cat /etc/sysctl.d/k8s.conf

sysctl --system  # 生效

还是先在外部操作再 copy

2.3.1.8 时间同步
# Ubuntu
sudo apt-get install ntpdate -y

# centos
yum install ntpdate -y

sudo ntpdate time.windows.com # ntpdate ntp1.aliyun.com

如果没有安装 yum, 可以通过sudo apt install yum 安装, 如果是 Ubuntu 就可以用 apt-get, yum 是 RedHat 系列的包管理工具

知识拓展

linux系统基本上分两大类:

  • RedHat系列:Redhat、Centos、Fedora等
  • Debian系列:Debian、Ubuntu等

RedHat 系列:

  • 常见的安装包格式 rpm 包,安装rpm包的命令是 “rpm -参数”
  • 包管理工具 yum
  • 支持 tar 包

Debian系列:

  • 常见的安装包格式 deb 包,安装deb包的命令是 “dpkg -参数”
  • 包管理工具 apt-get
  • 支持 tar 包

当看到下面输出时就说明成功了

master1@master1:~$ sudo ntpdate time.windows.com
 4 Feb 09:27:21 ntpdate[3614]: adjust time server 20.189.79.72 offset -0.000807 sec

2.3.2 所有节点安装Docker/kubeadm/kubelet

Kubernetes默认 CRI(容器运行时)为Docker,因此先安装Docker。

  • 设置 apt-get 镜像加速
node1@node1:~$ cp /etc/apt/sources.list ./sources.list
node1@node1:~$ vi sources.list
node1@node1:~$ sudo cp /etc/apt/sources.list /etc/apt/sources.list.back
node1@node1:~$ sudo cp ./sources.list /etc/apt/sources.list
apt-get update

# -------------- 镜像地址 ------
deb http://mirrors.cloud.aliyuncs.com/ubuntu/ trusty main restricted universe multiverse
deb http://mirrors.cloud.aliyuncs.com/ubuntu/ trusty-security main restricted universe multiverse
deb http://mirrors.cloud.aliyuncs.com/ubuntu/ trusty-updates main restricted universe multiverse
deb http://mirrors.cloud.aliyuncs.com/ubuntu/ trusty-proposed main restricted universe multiverse
deb http://mirrors.cloud.aliyuncs.com/ubuntu/ trusty-backports main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-backports main restricted universe multiverse
2.3.2.1 安装 docker
  • 卸载 docker (docker 版本和 k8s 版本必须匹配)


  • 安装
# Ubuntu
# 配置所需环境
sudo apt-get install \
 apt-transport-https \
 ca-certificates \
 curl \
 gnupg-agent \
 software-properties-common
 
 # 开始安装docker的gpg密钥
 curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
 # 验证可用密钥
 sudo apt-key fingerprint 0EBFCD88
 # 写入docker stable版本的阿里云镜像软件源
 sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"

# 安装最新版的docker-ce
# sudo apt-get install docker-ce docker-ce-cli # 安装最新的 docker ------ 注意 docker 版本和 k8s 版本需要保持一致
sudo apt-get install docker-ce=18.06.1~ce~3-0~ubuntu

# centos
$ wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
$ yum -y install docker-ce-18.06.1.ce-3.el7
$ systemctl enable docker && systemctl start docker
$ docker --version
Docker version 18.06.1-ce, build e68fc7a
  • 设置 docker 镜像加速
cat > ./daemon.json << EOF
{
  "registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"]
}
EOF

sudo cp ./daemon.json /etc/docker/daemon.json

sudo systemctl daemon-reload

sudo systemctl restart docker

如果您想以非root用户身份使用Docker,现在应该考虑使用类似以下方式将您的用户添加到“ docker”组:

sudo usermod -aG docker <your-user>

但是这需要注销重新登录才能使用.

2.3.2.3 设置 k8s 镜像源
# Ubuntu
sudo apt update && sudo apt install -y apt-transport-https curl
curl -s https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add -

echo "deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main"

cat <<EOF > ./kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF

sudo cp ./kubernetes.list /etc/apt/sources.list.d/kubernetes.list

# centos
$ cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
2.3.2.4 安装kubeadm,kubelet和kubectl
# Ubuntu
sudo apt update && sudo apt install -y kubelet=1.18.0-00 kubeadm=1.18.0-00 kubectl=1.18.0-00
systemctl enable kubelet  # 开机启动

# centos
yum install -y kubelet-1.18.0 kubeadm-1.18.0 kubectl-1.18.0
systemctl enable kubelet

2.3.3 部署Kubernetes Master

在 master 节点上执行

sudo kubeadm init --apiserver-advertise-address=192.168.3.18 --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.18.0 --service-cidr=10.1.0.0/16 --pod-network-cidr=10.244.0.0/16 --ignore-preflight-errors=all

Kubesphere DNS配置_Kubesphere DNS配置_06

注意 ip 为 Master Node 的 Ip 地址

这一步, kubeadm 会帮助我们下载很多必须的镜像, 如下图

Kubesphere DNS配置_k8s集群_07

按照提示配置一下内容, 使用kubectl工具:

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

2.3.3.4 加入Kubernetes Node

在 Node 节点上执行。向集群添加新节点,执行在kubeadm init输出的kubeadm join命令:

kubeadm join 192.168.3.26:6443 --token mtaujy.be4r3uhdpgix05gv     --discovery-token-ca-cert-hash sha256:0e524805dd05d25709ad7f49035e935387f034706cf009c0c6650f2a72baf62f

这一步类似 Master Node, kubeadm 也会帮我们安装一些必须的镜像.

Kubesphere DNS配置_docker_08

默认token有效期为24小时,当过期之后,该token就不可用了。这时就需要重新创建token,操作如下:

kubeadm token create --print-join-command

加入 node 后可以通过 kubectl get nodes 命令查看集群状态(这会集群还不能对外提供服务, 还需要安装一些网络插件).

Kubesphere DNS配置_kubernetes_09

2.3.3.5 部署CNI网络插件

wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

默认镜像地址无法访问,sed命令修改为docker hub镜像仓库。或者使用本地的(公众号后台回复 kube-yml 获取).
通过 scp 命令上传本地文件到 Linux:
scp /Users/dreamli/Downloads/kube-flannel.yaml root@192.168.3.26:/kube-flannel.yaml

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

Kubesphere DNS配置_k8s集群_10

安装完成后需要可以通过以下命令查看状态

kubectl get pods -n kube-system

Kubesphere DNS配置_k8s集群_11

Kubesphere DNS配置_Kubesphere DNS配置_12

这里需要等待一会, 直到所有容器都进入 running 状态, 并且所有 node 都进入 Ready 状态

Kubesphere DNS配置_Kubesphere DNS配置_13

过程中, 如果某台 Node 机器的 flannel 插件下载失败, 可以自行拉取镜像, 或者重新执行安装命令.

Kubesphere DNS配置_kubernetes_14

docker pull lizhenliang/flannel:v0.11.0-amd64

2.3.3.6 测试kubernetes集群

  • 在Kubernetes集群中创建一个pod,验证是否正常运行:
kubectl create deployment nginx --image=nginx
  • 查看安装状态, 直到容器进入 Running
kubectl get pod
  • 对外暴露服务
kubectl expose deployment nginx --port=80 --type=NodePort
  • 查看状态
kubectl get pod,svc
  • 访问测试, 通过任一 Node 的 Ip + 暴露的端口访问 nginx 服务

Kubesphere DNS配置_分布式_15