1 前言
之前写了篇文章《Mac上使用Docker Desktop启动Kubernetes,踩坑后终于搞掂》介绍了如何搭建一个Kubernetes
玩玩,但毕竟是单机版,今天我们来学习一下如何搭建Kubernetes
集群,更贴近生产,但还不能用于生产。
2 基本概念
首先贴一张来自官网的图:
通过这张图,我们就能大概知道我们需要安装什么,如何安装,而不是瞎操作。
2.1 控制面-master节点
左边是控制面,也就是master
节点,需要有:
etcd
作为存储集群信息的键值对数据库;
kube-api-server
对外公开K8s API
,是控制面的前端;
kube-scheduler
监视那些新创建的未指定运行节点的Pod
,并选择节点让Pod
在上面运行;
kube-controller-manager
控制器组件,如节点控制器、副本控制器、端点控制器等。
2.2 Node节点
右边是Node
节点,即计算和工作节点:
kubelet
在每个节点运行的代理,它保证容器运行在Pod
中;
kube-proxy
是节点的网络代理。
2.3 版本信息
本次操作的版本信息如下:
组件 | 版本号 | 说明 |
---|---|---|
操作系统 | Ubuntu 18.04 | 阿里云机器,2Cpu 4Gb内存 |
Docker | 19.3.13 | apt安装 |
Kubernetes | v1.19.0 | apt安装和容器化安装 |
3 机器准备
登陆阿里云,没有账号可以用支付宝登陆创建,购买机器时需要保证账号有100元,是因为很多服务是先使用、后付费的模式。登陆后进入控制台,点击左侧的云服务器ECS
,然后点击创建实例
:
3.1 机型选择
我之前已经有3台广州地区的机器了,这次例子我买华北地区的吧:
注意要选抢占式实例
,比较便宜;
地区就近原则就行,离你越近,网络连接应该越好,后面可用区
要选一个,不要随机分配
;
性能方面就选2Cpu 4Gb
;
买3台,一台master
,两台node
;
系统镜像选Ubuntu 18.04 64位
;
它会根据你的选择把价格实时计算出来,可以选一个最便宜的。
其它默认,按下一步。
3.2 网络设置
网络设置如下:
注意要分配公网IP
,不然无法连接;
选择按流量计费,因为按带宽计费很贵,然后把带宽峰值调到最大,加快后面下载软件和镜像;
安全组
把端口都打开吧。
3.3 设置密码
设置root
的登陆密码:
可能通过密钥或密码登陆,这里直接用密码的方式。
接着后面正常选就行了。
3.4 ssh连接测试
创建成功后,查看一下:
如果查看不到,就刷新一下,并选择对应的地区。可以看到上面三台机器的内网IP在都一个段上,完美!
通过ssh
软件和命令连接,测试是否正常,注意是要用公网的IP,如:
ssh root@39.104.25.81
4 搭建过程
4.1 系统基本设置
分别去对应的机器下配置一下hostname
,注意一台机器只执行其中一条命令:
hostnamectl set-hostname master01 --static
hostnamectl set-hostname node01 --static
hostnamectl set-hostname node02 --static
修改完后执行su
,就能看到变化了。
修改/etc/hosts
文件,注意下面是内网IP(三台机器都执行):
# pkslow-cluster
172.21.243.113 master01
172.21.243.114 node01
172.21.243.115 node02
关闭防火墙(三台机器都执行):
ufw disable
4.2 安装Docker(三台机器都执行)
4.2.1 必要的软件及密钥准备
更新源:
apt-get update
安装软件包以允许apt通过HTTPS使用存储库:
apt-get -y install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
添加Docker的官方GPG密钥:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
添加稳定的存储库:
add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
更新apt源:
apt-get update
4.2.2 安装docker
安装docker-ce最新版本:
apt-get -y install docker-ce docker-ce-cli containerd.io
这里装的东西比较大,可能需要等一段时间。
查看安装情况:
docker info
可能会出现警告:WARNING: No swap limit support
,这会影响后续对Docker
进行资源限制。
解决方案:修改/etc/default/grub
文件的如下配置为:
GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1 vga=792 console=tty0 console=ttyS0,115200n8 net.ifnames=0 noibrs"
更新后重启让它生效:
update-grub && reboot
将系统iptables 中 FORWARD 链的默认策略设置为ACCEPT
:
echo "iptables -P FORWARD ACCEPT" >> ~/.bashrc
source ~/.bashrc
4.2.3 阿里云镜像加速
设置阿里云镜像加速:
cat > /etc/docker/daemon.json <<EOF
{
"registry-mirrors": ["https://v00rv7a3.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
重启Docker
:
systemctl daemon-reload && systemctl restart docker.service
4.3 安装Kubernetes
4.3.1 安装必备软件包
安装软件kubelet
、kubeadm
和kubectl
(三台机器都执行):
# 配置apt
apt-get update && apt-get install -y apt-transport-https
# 配置key
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
# 添加阿里云镜像
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
# 更新源
apt-get update
# 安装
apt-get install -y kubelet kubeadm kubectl
开启这些设置使通过网桥的数据包由主机系统上的iptables规则处理,默认关闭,设置为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
4.3.2 控制面创建(只在master主机)
生成配置文件:
kubeadm config print init-defaults > init-defaults.yaml
修改配置文件init-defaults.yaml
的如下信息:
clusterName: pkslow-cluster
advertiseAddress: 172.21.243.113
imageRepository: registry.aliyuncs.com/google_containers
初始化master
:
kubeadm init --config init-defaults.yaml
成功后会有如下信息,并给出了node
节点如何加入集群的命令,把下面标红的命令复制下来:
4.3.3 节点加入集群
在两个节点(node01和node02)执行:
kubeadm join 172.21.243.113:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:2b425f0cb1f2609992ed8e3e3da2fd1c9db1f02381a7d8dcc9bfa4b5e607de97
4.3.4 检测集群情况(只在master)
为kubectl
指定配置文件:
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> /root/.bashrc
source /root/.bashrc
查看所有节点的状态:
kubectl get nodes
NAME STATUS ROLES AGE VERSION
master01 NotReady master 3m21s v1.19.3
node01 NotReady <none> 71s v1.19.3
node02 NotReady <none> 56s v1.19.3
发现STATUS
为NotReady
,是因为我们还没有安装网络组件。
安装网络:
kubectl apply -f https://docs.projectcalico.org/v3.14/manifests/calico.yaml
再次检测,已经Ready
了:
kubectl get nodes
NAME STATUS ROLES AGE VERSION
master01 Ready master 4m32s v1.19.3
node01 Ready <none> 2m22s v1.19.3
node02 Ready <none> 2m7s v1.19.3
5 验证
5.1 集群验证
查看集群信息:
# kubectl cluster-info
Kubernetes master is running at https://172.21.243.113:6443
KubeDNS is running at https://172.21.243.113:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
查看关键组件有没有正常运行:
# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-6dfcd885bf-9x7dp 1/1 Running 0 8h
calico-node-5fvm6 1/1 Running 0 8h
calico-node-ftkmk 1/1 Running 0 8h
calico-node-ql8jd 1/1 Running 0 8h
coredns-6d56c8448f-49ld7 1/1 Running 0 8h
coredns-6d56c8448f-hf9qv 1/1 Running 0 8h
etcd-master01 1/1 Running 0 8h
kube-apiserver-master01 1/1 Running 0 8h
kube-controller-manager-master01 1/1 Running 0 8h
kube-proxy-49r5z 1/1 Running 0 8h
kube-proxy-65pgs 1/1 Running 0 8h
kube-proxy-9w5h2 1/1 Running 0 8h
kube-scheduler-master01 1/1 Running 0 8h
5.2 运行一个应用验证
启动一个nginx
试试:
kubectl run nginx --image=nginx:1.19.0
查看发现已经正常运行:
kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 7h59m 192.168.196.130 node01 <none> <none>
发送GET
请求,查看nginx
的首页:
curl http://192.168.196.130
6 其它补充
该部分与之前使用的机器不同,IP已经变化。
6.1 给node添加label
安装完成后,节点显示的角色为空,需要添加标签:
kubectl label nodes node01 node-role.kubernetes.io/worker=
kubectl label nodes node02 node-role.kubernetes.io/worker=
这样就会正常显示角色:
$ kubectl get node
NAME STATUS ROLES AGE VERSION
master01 Ready master 7h34m v1.19.4
node01 Ready worker 7h32m v1.19.4
node02 Ready worker 7h31m v1.19.4
6.2 安装Ingress Controller
使用Github
上的一个yaml
文件直接apply:https://github.com/kubernetes/ingress-nginx/blob/ingress-nginx-3.10.1/deploy/static/provider/baremetal/deploy.yaml
但需要多添加一行代码,即在Deployment
上添加hostNetwork: true
,这样这些Pod
就会使用宿主的网络。添加如下:
spec:
hostNetwork: true
dnsPolicy: ClusterFirst
containers:
- name: controller
位置大概如图所示:
找到所在的node
,为node01
:
$ kubectl get pod -A -o wide | grep ingress
ingress-nginx ingress-nginx-admission-create-j82j4 0/1 Completed 0 26m 192.168.140.69 node02 <none> <none>
ingress-nginx ingress-nginx-admission-patch-lpw7t 0/1 Completed 0 26m 192.168.196.137 node01 <none> <none>
ingress-nginx ingress-nginx-controller-89bd8fb7c-zsnnx 1/1 Running 0 14m 172.17.144.117 node01 <none> <none>
则使用了Ingress
后,要按下面访问:
curl 172.17.144.117/nginx
6.3 安装Storage Class
需要安装一个StorageClass
,以便做其它实验。
6.3.1 安装NFS服务器
使用主节点做NFS服务器,在master
节点安装如下:
apt-get -y install nfs-kernel-server
创建目录并赋权:
mkdir /storage && echo "/storage *(rw,sync,no_root_squash)" >> /etc/exports
# 重启
systemctl restart nfs-kernel-server
6.3.2 node节点安装客户端
我们只在node
节点作为客户端,则只在node
节点安装:
apt-get -y install nfs-common
6.3.3 部署NFS Client插件
到Github下载class.yaml
、rbac.yaml
和deployment.yaml
文件,修改deployment.yaml
文件的服务器IP和目录:
env:
- name: PROVISIONER_NAME
value: fuseim.pri/ifs
- name: NFS_SERVER
value: 172.17.144.116
- name: NFS_PATH
value: /storage
volumes:
- name: nfs-client-root
nfs:
server: 172.17.144.116
path: /storage
全部apply
。
6.3.4 测试
创建一个StatefulSet
来测试:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx
serviceName: "nginx"
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteMany" ]
storageClassName: "managed-nfs-storage"
resources:
requests:
storage: 10Mi
检查:
$ kubectl get statefulsets.apps
NAME READY AGE
web 3/3 7m43s
$ ls /storage/
default-www-web-0-pvc-5379c52c-d052-4877-a0c2-8a04807a932c default-www-web-1-pvc-178bb758-d65d-44e8-86bc-137b727e996d default-www-web-2-pvc-21cddeb8-8612-4413-9ab9-7be8fbcb3a96
StatefulSet
正常启动,在/storage
目录成功创建了目录。
6.4 安装Metrics Server
安装前,无法获取:
kubectl top node
error: Metrics API not available
下载安装脚本:
wget https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.3.7/components.yaml
修改components.yaml
文件,在deployment
的args
增加参数如下:
args:
- --kubelet-insecure-tls
- --kubelet-preferred-address-types=InternalIP
apply
后,等一段时间,执行即可:
$ kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
master01 172m 8% 2039Mi 53%
node01 124m 6% 1612Mi 41%
node02 136m 6% 1433Mi 37%
7 重置集群
在三台机执行:
kubeadm reset
rm -rf /etc/kubernetes
对于master节点,还要执行:
rm -rf /var/lib/calico
然后重新执行:
kubeadm init --config init-defaults.yaml
kubectl apply -f https://docs.projectcalico.org/v3.11/manifests/calico.yaml
node
节点重新join
就行了。当然,Ingress Controller
等也要重新安装了。
8 总结
这是用于实验的搭建,实际生产环境会更复杂,起码master
不能是单节点,要高可用。但对于学习Kubernetes
而言,可以满足了。