kubeadm是Kubernetes官方提供的用于快速部署Kubernetes集群的工具,本篇文章使用kubeadm搭建一个单master节点的k8s集群。

节点部署信息

节点主机名 节点IP 节点角色 操作系统
k8s-master 10.10.55.113 master centos7.6
k8s-node1 10.10.55.114 node centos7.6

节点说明

master:控制节点。kube-apiserver负责API服务,kube-controller-manager负责容器编排,kube-scheduler负责调度

node:工作节点。kubelet 主要负责同容器运行时(比如 Docker 项目)打交道。而这个交互所依赖的,是一个称作 CRI(Container Runtime Interface)的远程调用接口,这个接口定义了容器运行时的各项核心操作,比如:启动一个容器需要的所有参数

master核心组件 node核心组件
kube-apiserver kubelet
kube-controller-manager  
kube-scheduler  

一、基础环境准备

以下操作无特殊说明均在每个节点执行。

修改主机名

#master节点:
hostnamectl set-hostname k8s-master
#node1节点:
hostnamectl set-hostname k8s-node1

基本配置

#修改/etc/hosts文件
cat >> /etc/hosts << EOF
10.10.55.113 k8s-master
10.10.55.114 k8s-node1
EOF #关闭防火墙和selinux
systemctl stop firewalld && systemctl disable firewalld
sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config && setenforce 0 #关闭swap
swapoff -a
yes | cp /etc/fstab /etc/fstab_bak
cat /etc/fstab_bak |grep -v swap > /etc/fstab

设置网桥包经过iptalbes

RHEL / CentOS 7上的一些用户报告了由于iptables被绕过而导致流量路由不正确的问题。创建/etc/sysctl.d/k8s.conf文件,添加如下内容:

cat <<EOF >  /etc/sysctl.d/k8s.conf
vm.swappiness = 0
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF # 使配置生效
modprobe br_netfilter
sysctl -p /etc/sysctl.d/k8s.conf

修改iptables filter表中FOWARD链的默认策略(pllicy)为ACCEPT

iptables -P FORWARD ACCEPT

kube-proxy开启ipvs的前提条件

由于ipvs已经加入到了内核的主干,所以为kube-proxy开启ipvs的前提需要加载以下的内核模块:
在所有的Kubernetes节点执行以下脚本:

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 #查看是否已经正确加载所需的内核模块
lsmod | grep -e ip_vs -e nf_conntrack_ipv4

上面脚本创建了/etc/sysconfig/modules/ipvs.modules文件,保证在节点重启后能自动加载所需模块。 使用lsmod | grep -e ip_vs -e nf_conntrack_ipv4命令查看是否已经正确加载所需的内核模块。
接下来还需要确保各个节点上已经安装了ipset软件包。 为了便于查看ipvs的代理规则,最好安装一下管理工具ipvsadm。

yum install ipset
yum install ipset ipvsadm -y

安装docker

Kubernetes默认的容器运行时仍然是Docker,使用的是kubelet中内置dockershim CRI实现。需要注意的是,Kubernetes 1.13最低支持的Docker版本是1.11.1,最高支持是18.06,而Docker最新版本已经是18.09了,故我们安装时需要指定版本为18.06.1-ce

#配置docker yum源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo #安装指定版本,这里安装18.06
yum list docker-ce --showduplicates | sort -r
yum install -y docker-ce-18.06.1.ce-3.el7
systemctl start docker && systemctl enable docker #启用docker
systemctl enable docker
sudo systemctl start docker #测试docker是否安装成功
docker run hello-world

安装kubeadm、kubelet、kubectl

官方安装文档可以参考:
https://kubernetes.io/docs/setup/independent/install-kubeadm/

kubelet 在群集中所有节点上运行的核心组件, 用来执行如启动pods和containers等操作。
kubeadm 引导启动k8s集群的命令行工具,用于初始化 Cluster。
kubectl 是 Kubernetes 命令行工具。通过 kubectl 可以部署和管理应用,查看各种资源,创建、删除和更新各种组件。

#配置kubernetes.repo的源,由于官方源国内无法访问,这里使用阿里云yum源
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 #在所有节点上安装指定版本 kubelet、kubeadm 和 kubectl
yum install -y kubelet-1.13.1 kubeadm-1.13.1 kubectl-1.13.1 #启动kubelet服务
systemctl enable kubelet && systemctl start kubelet

二、部署master节点

Master节点执行初始化:

注意这里执行初始化用到了- -image-repository选项,指定初始化需要的镜像源从阿里云镜像仓库拉取。--ignore-preflight-errors=Swap,忽略系统swap错误警告

kubeadm init \
--kubernetes-version=v1.13.1 \
--pod-network-cidr=10.244.0.0/16 \
--image-repository registry.aliyuncs.com/google_containers \
--apiserver-advertise-address=10.10.55.113 \
--ignore-preflight-errors=Swap

等待执行完成后,会看到类似如下的提示,后续加入kubernetes集群要用到

kubeadm join 10.10.55.113:6443 --token x66sy3.7e2u4um7etb3zk57 --discovery-token-ca-cert-hash sha256:147a0920ac265d668e54fea59af4fb570660eccd178ca1c247c0c018286478a3

配置 kubectl

kubectl 是管理 Kubernetes Cluster 的命令行工具,前面我们已经在所有的节点安装了 kubectl。Master 初始化完成后需要做一些配置工作,然后 kubectl 就能使用了。
依照 kubeadm init 输出的最后提示,推荐用 Linux 普通用户执行 kubectl。

创建普通用户centos

#创建普通用户并设置密码123456
useradd centos && echo "centos:123456" | chpasswd centos #追加sudo权限,并配置sudo免密
sed -i '/^root/a\centos ALL=(ALL) NOPASSWD:ALL' /etc/sudoers #保存集群安全配置文件到当前用户.kube目录
su - centos
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config #启用 kubectl 命令自动补全功能(注销重新登录生效)
echo "source <(kubectl completion bash)" >> ~/.bashrc

需要这些配置命令的原因是:Kubernetes 集群默认需要加密方式访问。所以,这几条命令,就是将刚刚部署生成的 Kubernetes 集群的安全配置文件,保存到当前用户的.kube 目录下,kubectl 默认会使用这个目录下的授权信息访问 Kubernetes 集群。
如果不这么做的话,我们每次都需要通过 export KUBECONFIG 环境变量告诉 kubectl 这个安全配置文件的位置。
配置完成后centos用户就可以使用 kubectl 命令管理集群了。

查看集群状态:

确认各个组件都处于healthy状态。

[root@k8s-master ~]# kubectl get cs
NAME STATUS MESSAGE ERROR
controller-manager Healthy ok
scheduler Healthy ok
etcd-0 Healthy {"health": "true"}

部署网络插件(这里使用flannerl)

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

kubectl apply -f  kube-flannel.yml

安装完成确保所有pod处于running状态

kubectl get pod --all-namespaces -o wide

#或者如下命令(-n kube-system意思为命名空间kube-system下pod的状态)
kubectl get pods -n kube-system

此时master节点的状态为ready

[root@k8s-master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready master 8d v1.13.1

安装出现问题

#日志 (coredns-78d4cf999f-qhb7p指 pod的name)
kubectl logs coredns-78d4cf999f-qhb7p -n kube-system #节点详情
kubectl describe pods coredns-78d4cf999f-qhb7p -n kube-system

尝试重新安装

kubeadm reset

ifconfig cni0 down
ip link delete cni0 ifconfig flannel.1 down
ip link delete flannel.1 rm -rf /var/lib/cni/

三、部署node节点

node加入kubernetes集群

#执行以下命令将节点接入集群
kubeadm join 10.10.55.113:6443 --token x66sy3.7e2u4um7etb3zk57 --discovery-token-ca-cert-hash sha256:147a0920ac265d668e54fea59af4fb570660eccd178ca1c247c0c018286478a3
#如果执行kubeadm init时没有记录下加入集群的命令,可以通过以下命令重新创建
kubeadm token create --print-join-command

查看节点状态

[root@k8s-master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready master 8d v1.13.1
k8s-node1 Ready <none> 8d v1.13.1

确保组件为running

[root@k8s-node1 ~]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-78d4cf999f-77ql5 1/1 Running 0 8d
coredns-78d4cf999f-qhb7p 1/1 Running 0 8d
etcd-k8s-master 1/1 Running 0 8d
kube-apiserver-k8s-master 1/1 Running 0 8d
kube-controller-manager-k8s-master 1/1 Running 1 8d
kube-flannel-ds-amd64-2272z 1/1 Running 0 8d
kube-flannel-ds-amd64-zlgxf 1/1 Running 0 8d
kube-proxy-hwptn 1/1 Running 0 8d
kube-proxy-p6cg2 1/1 Running 0 8d
kube-scheduler-k8s-master 1/1 Running 1 8d

如果pod状态为Pending、ContainerCreating、ImagePullBackOff 都表明 Pod 没有就绪,Running 才是就绪状态。
如果有pod提示失败,我们可以通过 kubectl describe pod 查看 Pod 具体情况,以具体分析解决问题

四、测试集群各个组件是否正常

首先验证kube-apiserver, kube-controller-manager, kube-scheduler, pod network 是否正常:
部署一个 Nginx Deployment,包含2个Pod

[root@k8s-node1 ~]# kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
my-saas-service 1/1 1 1 5d5h
my-saas-web 1/1 1 1 3d23h
[root@k8s-node1 ~]# kubectl create deployment nginx --image=nginx:alpine
deployment.apps/nginx created
[root@k8s-node1 ~]# kubectl scale deployment nginx --replicas=2
deployment.extensions/nginx scaled
[root@k8s-node1 ~]# kubectl get pods -l app=nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-54458cd494-cgqgf 1/1 Running 0 13s 10.244.1.36 k8s-node1 <none> <none>
nginx-54458cd494-gkhlb 1/1 Running 0 8s 10.244.1.37 k8s-node1 <none> <none>

再验证一下kube-proxy是否正常:

以 NodePort 方式对外提供服务

[root@k8s-node1 ~]# kubectl expose deployment nginx --port=80 --type=NodePort
service/nginx exposed
[root@k8s-node1 ~]# kubectl get services nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx NodePort 10.102.34.74 <none> 80:31782/TCP 4s

可以通过任意 NodeIP:Port 在集群外部访问这个服务:

[root@k8s-node1 ~]# curl 10.10.55.113:31782
[root@k8s-node1 ~]# curl 10.10.55.114:31782
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p> <p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p>
</body>
</html>

最后验证一下dns, pod network是否正常:

运行Busybox并进入交互模式

[root@k8s-node1 ~]# kubectl run -it curl --image=radial/busyboxplus:curl
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
If you don't see a command prompt, try pressing enter.

输入nslookup nginx查看是否可以正确解析出集群内的IP,以验证DNS是否正常

[ root@curl-66959f6557-rb2bm:/ ]$ nslookup nginx
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local Name: nginx
Address 1: 10.102.34.74 nginx.default.svc.cluster.local

通过服务名进行访问,验证kube-proxy是否正常

[ root@curl-66959f6557-rb2bm:/ ]$ curl http://nginx/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
...
</body>
</html>

退出 exit

kube-proxy开启ipvs

修改ConfigMap的kube-system/kube-proxy中的config.conf,mode: “ipvs”:

kubectl edit cm kube-proxy -n kube-system

之后重启各个节点上的kube-proxy pod:

kubectl get pod -n kube-system | grep kube-proxy | awk '{system("kubectl delete pod "$1" -n kube-system")}'

查看状态

kubectl get pod -n kube-system | grep kube-proxy

查看日志

kubectl logs kube-proxy-pf55q -n kube-system

日志中打印出了Using ipvs Proxier,说明ipvs模式已经开启。

备注:删除节点和集群

如何从集群中移除k8s-node2 (是k8s-node2)?

首先要排除节点,并确保该节点为空, 然后再将其关闭。

1. 在master节点上执行:

kubectl drain k8s-node2   --delete-local-data --force --ignore-daemonsets
kubectl delete node k8s-node2

2. 在子节点k8s-node2  上执行:

kubeadm reset
ifconfig cni0 down
ip link delete cni0
ifconfig flannel.1 down
ip link delete flannel.1
rm -rf /var/lib/cni/

3.在子节点 k8s-node1上执行

kubectl delete node k8s-node2 

注意:

在master上删除node并不会清理k8s-node2运行的容器,需要在删除节点上面手动运行清理命令。
如果你想重新配置集群,使用新的参数重新运行kubeadm init或者kubeadm join即可。

到此,kubeadm搭建kubernetes(v1.13.1)单节点集群搭建完成,后续可以继续添加node节点,或者部署dashboard、helm包管理工具、EFK日志系统、Prometheus Operator监控系统、rook+ceph存储系统等组件

参考:

https://blog.csdn.net/networken/article/details/84991940

https://www.kubernetes.org.cn/4956.html

关于kubernetes生产高可用集群搭建待续

kubernetes系列:(一)、kubeadm搭建kubernetes(v1.13.1)单节点集群的更多相关文章

  1. 使用Kubeadm搭建Kubernetes(1.12.2)集群

    Kubeadm是Kubernetes官方提供的用于快速安装Kubernetes集群的工具,伴随Kubernetes每个版本的发布都会同步更新,在2018年将进入GA状态,说明离生产环境中使用的距离越来 ...

  2. kubeadm搭建kubernetes集群之二:创建master节点

    在上一章kubeadm搭建kubernetes集群之一:构建标准化镜像中我们用VMware安装了一个CentOS7虚拟机,并且打算用这个虚拟机的镜像文件作为后续整个kubernetes的标准化镜像,现 ...

  3. kubeadm 搭建kubernetes集群环境

    需求 kubeadm 搭建kubernetes集群环境 准备条件 三台VPS(本文使用阿里云香港 - centos7.7) 一台能SSH连接到VPS的本地电脑 (推荐连接工具xshell) 安装步骤 ...

  4. kubeadm搭建kubernetes集群之三:加入node节点

    在上一章<kubeadm搭建kubernetes集群之二:创建master节点>的实战中,我们把kubernetes的master节点搭建好了,本章我们将加入node节点,使得整个环境可以 ...

  5. kubeadm安装K8S单master双节点集群

    宿主机:master:172.16.40.97node1:172.16.40.98node2:172.16.40.99 # 一.k8s初始化环境:(三台宿主机) 关闭防火墙和selinux syste ...

  6. kubernetes系列03—kubeadm安装部署K8S集群

    本文收录在容器技术学习系列文章总目录 1.kubernetes安装介绍 1.1 K8S架构图 1.2 K8S搭建安装示意图 1.3 安装kubernetes方法 1.3.1 方法1:使用kubeadm ...

  7. K8S学习笔记之二进制部署Kubernetes v1.13.4 高可用集群

    0x00 概述 本次采用二进制文件方式部署,本文过程写成了更详细更多可选方案的ansible部署方案 https://github.com/zhangguanzhang/Kubernetes-ansi ...

  8. centos7使用kubeadm搭建kubernetes集群

    一.本地实验环境准备 服务器虚拟机准备 IP CPU 内存 hostname 192.168.222.129 >=2c >=2G master 192.168.222.130 >=2 ...

  9. 使用kubeadm搭建Kubernetes(1.10.2)集群(国内环境)

    目录 目标 准备 主机 软件 步骤 (1/4)安装 kubeadm, kubelet and kubectl (2/4)初始化master节点 (3/4) 安装网络插件 (4/4)加入其他节点 (可选 ...

随机推荐

  1. C-数据和C

    1.常量与变量数据 有些数据在程序使用之前预先设定,并在整个运行过程中没有变化,叫做常量.另外的数据在程序运行过程中可能变化或被赋值,叫做变量. 2.数据类型关键字 对于变量,编译器通过声明语句中指定 ...

  2. 以shareExtension为例学习iOS扩展开发

    整体介绍 phone Extension 用法基础详解 share Extension 用法基础详解 demo链接   密码: i72z

  3. C# 分割URL地址

    public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_C ...

  4. angular 常用写法

    1.ng-repeat 数组数据中,不允许数组中有相同的两个数据,这个时候用下标去管理数据便可以解决这个问题 ng-repeat="item in list track by $index& ...

  5. Integer Intervals POJ - 1716_查分约束_

    Code: #include<cstdio> #include<queue> #include<algorithm> using namespace std; co ...

  6. google spanner

    REF 论文 google spanner spanner 介绍 http://blog.jobbole.com/110262/

  7. [置顶] HTTP 幂等性概念和应用

    转自:http://coolshell.cn/articles/4787.html HTTP 幂等性概念和应用 [ 感谢 Todd 同学 投递本文 ] 基于 HTTP 协议的 Web API 是时下最 ...

  8. 训练1-H

    小明今年3岁了, 现在他已经能够认识100以内的非负整数, 并且能够进行100以内的非负整数的加法计算. 对于大于等于100的整数, 小明仅保留该数的最后两位进行计算, 如果计算结果大于等于100, ...

  9. java的基本数据类型及运算符等

    基本数据类型 一.整数(整形) 值域 1. byte [-128,127] 2.short [-32768,32767] 3.int [-2147483648,2147483647] 4.long [ ...

  10. base64 编码的作用及原理

    Base64编码的作用:由于某些系统中只能使用ASCII字符.Base64就是用来将非ASCII字符的数据转换成ASCII字符的一种方法.它使用下面表中所使用的字符与编码. 而且base64特别适合在 ...