一、Kubernetes 整体概述和架构

Kubernetes 是什么

Kubernetes 是一个轻便的和可扩展的开源平台,用于管理容器化应用和服务。通过 Kubernetes 能够进行应用的自动化部署和扩缩容。在 Kubernetes 中,会将组成应用的容器组合成一个逻辑单元以更易管理和发现。Kubernetes 积累了作为 Google 生产环境运行工作负载 15 年的经验,并吸收了来自于社区的最佳想法和实践。Kubernetes 经过这几年的快速发展,形成了一个大的生态环境,Google 在 2014 年将 Kubernetes 作为开源项目。Kubernetes 的关键特性包括:

  • 自动化装箱:在不牺牲可用性的条件下,基于容器对资源的要求和约束自动部署容器。同时,为了提高利用率和节省更多资源,将关键和最佳工作量结合在一起。

  • 自愈能力:当容器失败时,会对容器进行重启;当所部署的 Node 节点有问题时,会对容器进行重新部署和重新调度;当容器未通过监控检查时,会关闭此容器;直到容器正常运行时,才会对外提供服务。

  • 水平扩容:通过简单的命令、用户界面或基于 CPU 的使用情况,能够对应用进行扩容和缩容。

  • 服务发现和负载均衡:开发者不需要使用额外的服务发现机制,就能够基于 Kubernetes 进行服务发现和负载均衡。

  • 自动发布和回滚:Kubernetes 能够程序化的发布应用和相关的配置。如果发布有问题,Kubernetes 将能够回归发生的变更。

  • 保密和配置管理:在不需要重新构建镜像的情况下,可以部署和更新保密和应用配置。

  • 存储编排:自动挂接存储系统,这些存储系统可以来自于本地、公共云提供商(例如:GCP 和 AWS)、网络存储 (例如:NFS、iSCSI、Gluster、Ceph、Cinder 和 Floker 等)。

Kubernetes 的整体架构

Kubernetes 属于主从分布式架构,主要由 Master Node 和 Worker Node 组成,以及包括客户端命令行工具 kubectl 和其它附加项。

  • Master Node:作为控制节点,对集群进行调度管理;Master Node 由 API Server、Scheduler、Cluster State Store 和 Controller-Manger Server 所组成;

  • Worker Node:作为真正的工作节点,运行业务应用的容器;Worker Node 包含 kubelet、kube proxy 和 Container Runtime;

  • kubectl:用于通过命令行与 API Server 进行交互,而对 Kubernetes 进行操作,实现在集群中进行各种资源的增删改查等操作;

  • Add-on:是对 Kubernetes 核心功能的扩展,例如增加网络和网络策略等能力。

Master Node(主节点)

API Server(API 服务器)

API Server 主要用来处理 REST 的操作,确保它们生效,并执行相关业务逻辑,以及更新 etcd(或者其他存储)中的相关对象。API Server 是所有 REST 命令的入口,它的相关结果状态将被保存在 etcd(或其他存储)中。API Server 的基本功能包括:

  • REST 语义,监控,持久化和一致性保证,API 版本控制,放弃和生效

  • 内置准入控制语义,同步准入控制钩子,以及异步资源初始化

  • API 注册和发现

另外,API Server 也作为集群的网关。默认情况,客户端通过 API Server 对集群进行访问,客户端需要通过认证,并使用 API Server 作为访问 Node 和 Pod(以及 service)的堡垒和代理 / 通道。

Cluster state store(集群状态存储)

1.  Kubernetes默认使用etcd作为集群整体存储,当然也可以使用其它的技术。etcd是一个简单的、分布式的、一致的key-value存储,主要被用来共享配置和服务发现。etcd提供了一个CRUD操作的REST API,以及提供了作为注册的接口,以监控指定的Node。集群的所有状态都存储在etcd实例中,并具有监控的能力,因此当etcd中的信息发生变化时,就能够快速的通知集群中相关的组件。

Controller-Manager Server(控制管理服务器)

1.  Controller-Manager Serve用于执行大部分的集群层次的功能,它既执行生命周期功能(例如:命名空间创建和生命周期、事件垃圾收集、已终止垃圾收集、级联删除垃圾收集、node垃圾收集),也执行API业务逻辑(例如:pod的弹性扩容)。控制管理提供自愈能力、扩容、应用生命周期管理、服务发现、路由、服务绑定和提供。Kubernetes默认提供Replication Controller、Node Controller、Namespace Controller、Service Controller、Endpoints Controller、Persistent Controller、DaemonSet Controller等控制器。

Scheduler(调度器)

1.  scheduler组件为容器自动选择运行的主机。依据请求资源的可用性,服务请求的质量等约束条件,scheduler监控未绑定的pod,并将其绑定至特定的node节点。Kubernetes也支持用户自己提供的调度器,Scheduler负责根据调度策略自动将Pod部署到合适Node中,调度策略分为预选策略和优选策略,Pod的整个调度过程分为两步:3.  )预选Node:遍历集群中所有的Node,按照具体的预选策略筛选出符合要求的Node列表。如没有Node符合预选策略规则,该Pod就会被挂起,直到集群中出现符合要求的Node。5.  )优选Node:预选Node列表的基础上,按照优选策略为待选的Node进行打分和排序,从中获取最优Node。

Worker Node(从节点)

Kubelet

1.  Kubelet是Kubernetes中最主要的控制器,它是Pod和Node API的主要实现者,Kubelet负责驱动容器执行层。在Kubernetes中,应用容器彼此是隔离的,并且与运行其的主机也是隔离的,这是对应用进行独立解耦管理的关键点。3.  在Kubernets中,Pod作为基本的执行单元,它可以拥有多个容器和存储数据卷,能够方便在每个容器中打包一个单一的应用,从而解耦了应用构建时和部署时的所关心的事项,已经能够方便在物理机/虚拟机之间进行迁移。API准入控制可以拒绝或者Pod,或者为Pod添加额外的调度约束,但是Kubelet才是Pod是否能够运行在特定Node上的最终裁决者,而不是scheduler或者DaemonSet。kubelet默认情况使用cAdvisor进行资源监控。负责管理Pod、容器、镜像、数据卷等,实现集群对节点的管理,并将容器的运行状态汇报给Kubernetes API Server。

Container Runtime(容器运行时)

1.  每一个Node都会运行一个Container Runtime,其负责下载镜像和运行容器。Kubernetes本身并不停容器运行时环境,但提供了接口,可以插入所选择的容器运行时环境。kubelet使用Unix socket之上的gRPC框架与容器运行时进行通信,kubelet作为客户端,而CRI shim作为服务器。

1.  protocol buffers API提供两个gRPC服务,ImageService和RuntimeService。ImageService提供拉取、查看、和移除镜像的RPC。RuntimeSerivce则提供管理Pods和容器生命周期管理的RPC,以及与容器进行交互(exec/attach/port-forward)。容器运行时能够同时管理镜像和容器(例如:Docker和Rkt),并且可以通过同一个套接字提供这两种服务。在Kubelet中,这个套接字通过–container-runtime-endpoint和–image-service-endpoint字段进行设置。Kubernetes CRI支持的容器运行时包括docker、rkt、cri-o、frankti、kata-containers和clear-containers等。

kube proxy

1.  基于一种公共访问策略(例如:负载均衡),服务提供了一种访问一群pod的途径。此方式通过创建一个虚拟的IP来实现,客户端能够访问此IP,并能够将服务透明的代理至Pod。每一个Node都会运行一个kube-proxy,kube proxy通过iptables规则引导访问至服务IP,并将重定向至正确的后端应用,通过这种方式kube-proxy提供了一个高可用的负载均衡解决方案。服务发现主要通过DNS实现。3.  在Kubernetes中,kube proxy负责为Pod创建代理服务;引到访问至服务;并实现服务到Pod的路由和转发,以及通过应用的负载均衡。

kubectl

kubectl 是 Kubernetes 集群的命令行接口。运行 kubectl 命令的语法如下所示:

1.  $ kubectl [command] [TYPE] [NAME] [flags]

这里的 command,TYPE、NAME 和 flags 为:

  • comand:指定要对资源执行的操作,例如 create、get、describe 和 delete

  • TYPE:指定资源类型,资源类型是大小学敏感的,开发者能够以单数、复数和缩略的形式。例如:

  • NAME:指定资源的名称,名称也大小写敏感的。如果省略名称,则会显示所有的资源,例如:

1.  $kubectl get pods
  • flags:指定可选的参数。例如,可以使用 - s 或者–server 参数指定 Kubernetes API server 的地址和端口。

另外,可以通过运行 kubectl help 命令获取更多的信息。

附加项和其他依赖

在 Kunbernetes 中可以以附加项的方式扩展 Kubernetes 的功能,目前主要有网络、服务发现和可视化这三大类的附加项,下面是可用的一些附加项:

网络和网络策略

  • ACI 通过与 Cisco ACI 集成的容器网络和网络安全。

  • Calico 是一个安全的 3 层网络和网络策略提供者。

  • Canal 联合 Fannel 和 Calico,通过网络和网络侧。

  • Cilium 是一个 3 层网络和网络侧插件,它能够透明的加强 HTTP/API/L7 策略。其即支持路由,也支持 overlay/encapsultion 模式。

  • Flannel 是一个 overlay 的网络提供者。

服务发现

  • CoreDNS 是一个灵活的,可扩展的 DNS 服务器,它能够作为 Pod 集群内的 DNS 进行安装。

  • Ingress 提供基于 Http 协议的路由转发机制。

可视化 & 控制

  • Dashboard 是 Kubernetes 的 web 用户界面。

二、k8s 搭建

kubeadm 是 Kubernetes 官方提供的用于快速安装 Kubernetes 集群的工具,伴随 Kubernetes 每个版本的发布都会同步更新,kubeadm 会对集群配置方面的一些实践做调整,通过实验 kubeadm 可以学习到 Kubernetes 官方在集群配置上一些新的最佳实践。

在 Kubernetes 的文档 Creating a single master cluster with kubeadm 中已经给出了目前 kubeadm 的主要特性已经处于 beta 状态了,在 2018 年将进入 GA 状态,说明 kubeadm 离可以在生产环境中使用的距离越来越近了。

当然我们线上稳定运行的 Kubernetes 集群是使用 ansible 以二进制形式的部署的高可用集群,这里体验 Kubernetes 1.11 中的 kubeadm 是为了跟随官方对集群初始化和配置方面的最佳实践,进一步完善我们的 ansible 部署脚本。

环境准备

环境说明

| 操作系统 | 主机名 | IP 地址 | 功能 | | ubuntu-16.04.5-server-amd64 | k8s-master001 | 192.168.91.128 | 主节点 | | ubuntu-16.04.5-server-amd64 | k8s-node001 | 192.168.91.129 | 从节点, etcd | | ubuntu-16.04.5-server-amd64 | k8s-node002 | 192.168.91.131 | 从节点, docker registry,Ubuntu 私有源 |

3 台服务器的配置均为:1 核 2G,硬盘 20G

请确保主节点能 ssh 免密登录 2 个从节点。3 台服务器,主要使用 root 用户操作

etcd 这里只用 1 个,如果要做高可用,请保证节点数量是奇数。比如 3,5,7。偶数节点,会无法选举 Leader

由于 k8s 需要的 docker 镜像和 deb 包被墙了。所以需要构建私有的 docker 仓库

相关软件包已经上传到百度云,下载方式为:

链接:https://pan.baidu.com/s/1Z31IcS2f15ufoqDw19-i3Q  提取码:tlex

其中 deb 包,是 ubuntu 的软件包,其他压缩包,全部都是 docker 镜像!

docker 镜像都是从 google 下载的,如果不放心,可自行下载!

如果你使用的是 Centos 7 系统,可以不用这么麻烦,使用开源 Breeze 工具部署 Kubernetes。

Breeze 项目是深圳睿云智合所开源的 Kubernetes 图形化部署工具,大大简化了 Kubernetes 部署的步骤,其最大亮点在于支持全离线环境的部署,且不需要翻墙获取 Google 的相应资源包,尤其适合某些不便访问互联网的服务器场景。

具体操作,请参考链接:

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

主机名

登录 3 台服务器,查看主机名

1.  cat /etc/hostname

如果输出不是上面表格中的主机名,请务必修改!

修改完成之后,必须要重启服务器才行!

由于这里并没有使用私有的 DNS,所以直接用 hosts 文件来强制解析。

务必保证 3 台服务器的 hosts 文件有如下 3 条记录

1.  192.168.91.128 k8s-master0012.  192.168.91.129 k8s-node0013.  192.168.91.131 k8s-node002

时间设置

务必保证 3 台服务器的时区是一样的,强制更改时区为上海,执行以下命令

1.  ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime2.  bash -c "echo 'Asia/Shanghai' > /etc/timezone"

安装 ntpdate

1.  apt-get install -y ntpdate

如果出现以下错误

1.  E: Could not get lock /var/lib/dpkg/lock - open (: Resource temporarily unavailable)2.  E: Unable to lock the administration directory (/var/lib/dpkg/), is another process using it?

执行 2 个命令解决

1.  sudo rm /var/cache/apt/archives/lock2.  sudo rm /var/lib/dpkg/lock

使用阿里云的时间服务器更新

1.  ntpdate ntp1.aliyun.com

3 台服务器都执行一下,确保时间一致!

请确保防火墙都关闭了!

ssh 免密登录

3 台服务器生成秘钥,并写入到 authorized_keys

1.  ssh-keygen -t rsa -P "" -f ~/.ssh/id_rsa2.  cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

登录到主节点服务器,copy 秘钥,执行以下命令

1.  ssh-copy-id k8s-master0012.  ssh-copy-id k8s-node0013.  ssh-copy-id k8s-node002

测试 ssh 免密登录

登录到主节点服务器,测试 ssh 免密登录

1.  ssh k8s-master0012.  exit4.  ssh k8s-node0015.  exit7.  ssh k8s-node0028.  exit

请确保以上 3 个命令,不需要输入密码

更新 ubuntu 数据库

使用阿里云的更新源,默认的太慢了

1.  vi /etc/apt/sources.list

清空文件内容,添加如下内容:

1.  deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted2.  deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted3.  deb http://mirrors.aliyun.com/ubuntu/ xenial universe4.  deb http://mirrors.aliyun.com/ubuntu/ xenial-updates universe5.  deb http://mirrors.aliyun.com/ubuntu/ xenial multiverse6.  deb http://mirrors.aliyun.com/ubuntu/ xenial-updates multiverse7.  deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse8.  deb http://mirrors.aliyun.com/ubuntu xenial-security main restricted9.  deb http://mirrors.aliyun.com/ubuntu xenial-security universe10.  deb http://mirrors.aliyun.com/ubuntu xenial-security multiverse

使用 apt-get update 来更新一下

1.  apt-get update

确保 3 台都是使用阿里云的更新源

3 台服务器,都需要安装 docker

1.  apt-get install -y docker.io

修改 daemon.json

1.  vim /etc/docker/daemon.json

内容如下:

1.  {2.  "registry-mirrors": [3.  "https://kv3qfp85.mirror.aliyuncs.com"4.  ],5.  "insecure-registries": [6.  "192.168.91.131:5000"7.  ]8.  }

重启 docker 服务

1.  systemctl restart docker

** 确保 3 台服务器,都修改了 daemon.json**

etcd 部署

登录到 k8s-node001 服务器,直接运行 etcd_v3.3.10.sh 即可。请注意前置条件!

etcd_v3.3.10.sh

说明:本脚本,只能在本地服务器安装。请确保 etcd-v3.3.10-linux-amd64.tar.gz 文件和 shell 脚本在同一目录下。

脚本附带了使用 systemctl 命令启动 etcd 服务

1.  #/bin/bash2.  # 单击版etcd安装脚本3.  # 本脚本,只能在本地服务器安装。4.  # 请确保etcd-v3.3.10-linux-amd64.tar.gz文件和当前脚本在同一目录下。5.  # 务必使用root用户执行此脚本!6.  # 确保可以直接执行python3,因为倒数第4行,有一个json格式化输出。如果不需要可以忽略7.  #set -e9.  # 输入本机ip10.  while true11.  do12.  echo '请输入本机ip'13.  echo 'Example: 192.168.0.1'14.  echo -e "etcd server ip=\c"15.  read ETCD_Server16.  if [ "$ETCD_Server" == "" ];then17.  echo 'No input etcd server IP'18.  else19.  #echo 'No input etcd server IP'20.  break21.  fi22.  done24.  # etcd启动服务25.  cat > /lib/systemd/system/etcd.service <<EOF26.  [Unit]27.  Description=etcd - highly-available key value store28.  Documentation=https://github.com/coreos/etcd29.  Documentation=man:etcd30.  After=network.target31.  Wants=network-online.target33.  [Service]34.  Environment=DAEMON_ARGS=35.  Environment=ETCD_NAME=%H36.  Environment=ETCD_DATA_DIR=/var/lib/etcd/default37.  EnvironmentFile=-/etc/default/%p38.  Type=notify39.  User=etcd40.  PermissionsStartOnly=true41.  #ExecStart=/bin/sh -c "GOMAXPROCS=\$(nproc) /usr/bin/etcd \$DAEMON_ARGS"42.  ExecStart=/usr/bin/etcd \$DAEMON_ARGS43.  Restart=on-abnormal44.  #RestartSec=10s45.  #LimitNOFILE=47.  [Install]48.  WantedBy=multi-user.target49.  Alias=etcd3.service50.  EOF52.  # 主机名53.  name=`hostname`54.  # etcd的http连接地址55.  initial_cluster="http://$ETCD_Server:2380"57.  # 判断进程是否启动58.  A=`ps -ef|grep /usr/bin/etcd|grep -v grep|wc -l`59.  if [ $A -ne  ];then60.  # 杀掉进程61.  killall etcd62.  fi 64.  # 删除etcd相关文件65.  rm -rf /var/lib/etcd/*66.  rm -rf /etc/default/etcd68.  # 设置时区69.  ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime71.  # 判断压缩文件72.  if [ ! -f "etcd-v3.3.10-linux-amd64.tar.gz" ];then73.  echo "当前目录etcd-v3.3.10-linux-amd64.tar.gz文件不存在"74.  exit75.  fi77.  # 安装etcd78.  tar zxf etcd-v3.3.10-linux-amd64.tar.gz -C /tmp/79.  cp -f /tmp/etcd-v3.3.10-linux-amd64/etcd /usr/bin/80.  cp -f /tmp/etcd-v3.3.10-linux-amd64/etcdctl /usr/bin/82.  # etcd配置文件83.  cat > /etc/default/etcd <<EOF84.  ETCD_NAME=$name85.  ETCD_DATA_DIR="/var/lib/etcd/"86.  ETCD_LISTEN_PEER_URLS="http://$ETCD_Server:2380"87.  ETCD_LISTEN_CLIENT_URLS="http://$ETCD_Server:2379,http://127.0.0.1:4001"88.  ETCD_INITIAL_ADVERTISE_PEER_URLS="http://$ETCD_Server:2380"89.  ETCD_INITIAL_CLUSTER="$ETCD_Servernitial_cluster"90.  ETCD_INITIAL_CLUSTER_STATE="new"91.  ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster-sdn"92.  ETCD_ADVERTISE_CLIENT_URLS="http://$ETCD_Server:2379"93.  EOF95.  # 临时脚本,添加用户和组96.  cat  > /tmp/foruser <<EOF97.  #!/bin/bash98.  if [ \`cat /etc/group|grep etcd|wc -l\` -eq 0 ];then groupadd -g 217 etcd;fi99.  if [ \`cat /etc/passwd|grep etcd|wc -l\` -eq 0 ];then mkdir -p /var/lib/etcd && useradd -g 217 -u 111 etcd -d /var/lib/etcd/ -s /bin/false;fi100.  if [ \`cat /etc/profile|grep ETCDCTL_API|wc -l\` -eq 0 ];then bash -c "echo 'export ETCDCTL_API=3' >> /etc/profile" && bash -c "source /etc/profile";fi101.  EOF103.  # 执行脚本104.  bash /tmp/foruser106.  # 启动服务107.  systemctl daemon-reload108.  systemctl enable etcd.service109.  chown -R etcd:etcd /var/lib/etcd110.  systemctl restart etcd.service111.  #netstat -anpt | grep 2379112.  # 查看版本113.  etcdctl -v114.  # 访问API, -s 去掉curl的统计信息. python3 -m json.tool 表示json格式化115.  curl $initial_cluster/version -s | python3 -m json.tool117.  # 删除临时文件118.  rm -rf /tmp/foruser /tmp/etcd-v3.3.10-linux-amd64

执行脚本

1.  bash etcd_v3.3.10.sh

输出:

1.  请输入本机ip2.  Example: 192.168.0.13.  etcd server ip=192.168.91.1294.  Created symlink from /etc/systemd/system/etcd3.service to /lib/systemd/system/etcd.service.5.  Created symlink from /etc/systemd/system/multi-user.target.wants/etcd.service to /lib/systemd/system/etcd.service.6.  etcdctl version: 3.3.107.  API version: 28.  {9.  "etcdserver": "3.3.10",10.  "etcdcluster": "3.3.0"11.  }

搭建 docker 私有仓库

登录到 k8s-node002 服务器,安装 docker

1.  apt-get install -y docker.io

拉取 registry 镜像

1.  docker pull registry

创建 registry docker 进程

1.  docker run -d --name docker-registry --restart=always -p : registry

上面已经修改过了 /etc/docker/daemon.json,所以这里不需要修改了!

创建目录 / reop,将百度云的 k8s-1.11 下载下来,上传到 / repo 目录。

1.  mkdir /repo

repo 的目录结构如下:

1.  /repo/2.  └── k8s-1.113.  ├── calico_cni_v1.11.4.tar.gz4.  ├── calico_kube-controllers_v1.0.3.tar.gz5.  ├── calico_node_v2.6.8.tar.gz6.  ├── calico.yaml7.  ├── coredns-1.1..tar.gz8.  ├── cri-tools_1.11.0-00_amd64_768e5551f9badfde12b10c42c88afb45c412c1bf307a5985a4b29f4499d341bd.deb9.  ├── kubeadm_1.11.2-00_amd64_7602f5c4362b9c17aba83e8424830a98ca66074e36dead31d239f2beda91f1ff.deb10.  ├── kube-apiserver.tar.gz11.  ├── kube-controller-manager.tar.gz12.  ├── kubectl_1.11.2-00_amd64_49e2a857e4852da0c27e3e92bc92fef4d33db7c93c2a4628cb9374e3a486bc92.deb13.  ├── kubelet_1.11.2-00_amd64_7537d39713573280e1cc245915fc7565ac49d041fbd0e0515daa1ea2ac659dbb.deb14.  ├── kube-proxy.tar.gz15.  ├── kubernetes-cni_0.6.0-00_amd64_43460dd3c97073851f84b32f5e8eebdc84fadedb5d5a00d1fc6872f30a4dd42c.deb16.  ├── kube-scheduler.tar.gz17.  └── pause3..tar.gz

测试 etcd 的状态,运行是否正常

测试 docker 私有仓库,运行是否正常

kubernetes Master 配置

以下都是主节点操作,从节点不需要做任何操作!

安装 kubernetes 服务器

复制软件包

1.  scp -r 192.168.91.131:/repo/k8s-1.11 ./

安装相关组件

1.  apt-get install -y docker.io ipvsadm ebtables socat --allow-unauthenticated

安装 k8s 的 deb 包

1.  dpkg -i k8s-1.11/*.deb

开启 cadvisor

1.  sed -i 's?config.yaml?config.yaml --cadvisor-port=4194?g' /etc/systemd/system/kubelet.service.d/-kubeadm.conf

这条命令的意思就是将 config.yaml 替换为 config.yaml --cadvisor-port=4194

添加 cgroup 驱动程序

1.  sed -i 8i'Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=cgroupfs"' /etc/systemd/system/kubelet.service.d/-kubeadm.conf

8i 表示 在第 8 行之前插入文本,文本的内容就是 Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=cgroupfs

重新应用配置

1.  systemctl daemon-reload

导入 k8s 镜像

1.  for i in k8s-1.11/*.gz; do sudo docker load < $i; done

查看当前镜像

1.  root@k8s-master001:~# docker images2.  REPOSITORY                                 TAG                 IMAGE ID            CREATED             SIZE3.  k8s.gcr.io/kube-apiserver-amd64            v1.11.2             214c48e87f58         months ago         MB4.  k8s.gcr.io/kube-controller-manager-amd64   v1.11.2             55b70b420785         months ago         MB5.  k8s.gcr.io/kube-proxy-amd64                v1.11.2             1d3d7afd77d1         months ago        97.8 MB6.  k8s.gcr.io/kube-scheduler-amd64            v1.11.2             0e4a34a3b0e6         months ago        56.8 MB7.  k8s.gcr.io/coredns                         1.1\.               b3b94275d97c         months ago        45.6 MB8.  quay.io/calico/node                        v2.6.8              e96a297310fd         months ago         MB9.  quay.io/calico/cni                         v1.11.4             4c4cb67d7a88         months ago        70.8 MB10.  quay.io/calico/kube-controllers            v1.0.3              34aebe64326d         months ago       52.3 MB11.  k8s.gcr.io/pause                           3.1                 da86e6ba6ca1         months ago        kB

将包含 quay.io 镜像推送到私有仓库

1.  docker tag quay.io/calico/cni:v1.11.4 192.168.91.131:/calico/cni:v1.11.42.  docker push 192.168.91.131:/calico/cni:v1.11.44.  docker tag quay.io/calico/kube-controllers:v1.0.3 192.168.91.131:/calico/kube-controllers:v1.0.35.  docker push 192.168.91.131:/calico/kube-controllers:v1.0.37.  docker tag quay.io/calico/node:v2.6.8 192.168.91.131:/calico/node:v2.6.88.  docker push 192.168.91.131:/calico/node:v2.6.8

这一步操作,可能有点麻烦,可以使用 shell 脚本完成

push_mirror.sh

1.  #!/bin/bash3.  # 私有仓库地址4.  dockerREG="192.168.91.131:5000"6.  # 查询包含calico的镜像7.  CalicoPro=$(sudo docker images|grep quay.io|awk -F 'quay.io/' '{print $2}'|awk '{print $1}'|sort|uniq)8.  for i in $CalicoPro;do9.  # 查询镜像的tag版本10.  Proversion=$(docker images|grep quay.io|grep $i|awk '{print $2}')11.  for j in $Proversion;do12.  # 打tag并推送镜像到私有仓库13.  sudo docker tag quay.io/$i:$j $dockerREG/$i:$j14.  sudo docker push $dockerREG/$i:$j15.  done16.  done

执行脚本

1.  bash push_mirror.sh

暂时关闭 kubelet

1.  # 重新设置kubelet服务开机启动2.  systemctl enable kubelet.service3.  # 停止kubelet服务4.  systemctl stop kubelet.service

关闭 swap

Kubernetes 1.8 开始要求关闭系统的 Swap,如果不关闭,默认配置下 kubelet 将无法启动。

关闭系统的 Swap 方法如下

1.  swapoff -a

修改 /etc/fstab 文件,注释掉 SWAP 的自动挂载,使用 free -m 确认 swap 已经关闭

1.  fswap=`cat /etc/fstab |grep swap|awk '{print $1}'`2.  for i in $fswap;do3.  sed -i "s?$i?#$i?g" /etc/fstab4.  done

上面这段代码表示,包含 swap 的行前面添加#

删除默认的 k8s 文件

1.  rm -rf /etc/kubernetes/*2.  rm -rf /var/lib/kubelet/*

重置 k8s 集群

1.  kubeadm reset -f

编辑临时配置文件

1.  vim /tmp/kubeadm-conf.yaml

内容如下:

1.  apiVersion: kubeadm.k8s.io/v1alpha12.  kind: MasterConfiguration3.  networking:4.  podSubnet: 192.138.0.0/5.  #apiServerCertSANs:6.  #- master017.  #- master028.  #- master039.  #- 172.16.2.110.  #- 172.16.2.211.  #- 172.16.2.312.  #- 172.16.2.10013.  etcd:14.  endpoints:15.  - http://192.168.91.129:237916.  #token: 67e411.zc3617bb21ad7ee317.  kubernetesVersion: v1.11.218.  api:19.  advertiseAddress: 192.168.91.128

注意修改主节点的 IP 和 etcd 的 IP 地址

定义 podSubnet 为 192.138.0.0/16

初始化集群

使用 kubeadm init 初始化集群

1.  kubeadm init --config=/tmp/kubeadm-conf.yaml| sudo tee /etc/kube-server-key

执行输出:

1.  [init] using Kubernetes version: v1.11.22.  [preflight] running pre-flight checks3.  I1113 ::57.910361    kernel_validator.go:] Validating kernel version4.  I1113 ::57.910897    kernel_validator.go:] Validating kernel config5.  [preflight/images] Pulling images required for setting up a Kubernetes cluster6.  [preflight/images] This might take a minute or two, depending on the speed of your internet connection7.  [preflight/images] You can also perform this action in beforehand using 'kubeadm config images pull'8.  [kubelet] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"9.  [kubelet] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"10.  [preflight] Activating the kubelet service11.  [certificates] Generated ca certificate and key.12.  [certificates] Generated apiserver certificate and key.13.  [certificates] apiserver serving cert is signed for DNS names [k8s-master001 kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 192.168.91.128]14.  [certificates] Generated apiserver-kubelet-client certificate and key.15.  [certificates] Generated sa key and public key.16.  [certificates] Generated front-proxy-ca certificate and key.17.  [certificates] Generated front-proxy-client certificate and key.18.  [certificates] valid certificates and keys now exist in "/etc/kubernetes/pki"19.  [kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/admin.conf"20.  [kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/kubelet.conf"21.  [kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/controller-manager.conf"22.  [kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/scheduler.conf"23.  [controlplane] wrote Static Pod manifest for component kube-apiserver to "/etc/kubernetes/manifests/kube-apiserver.yaml"24.  [controlplane] wrote Static Pod manifest for component kube-controller-manager to "/etc/kubernetes/manifests/kube-controller-manager.yaml"25.  [controlplane] wrote Static Pod manifest for component kube-scheduler to "/etc/kubernetes/manifests/kube-scheduler.yaml"26.  [init] waiting for the kubelet to boot up the control plane as Static Pods from directory "/etc/kubernetes/manifests"27.  [init] this might take a minute or longer if the control plane images have to be pulled28.  [apiclient] All control plane components are healthy after 44.009208 seconds29.  [uploadconfig] storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace30.  [kubelet] Creating a ConfigMap "kubelet-config-1.11" in namespace kube-system with the configuration for the kubelets in the cluster31.  [markmaster] Marking the node k8s-master001 as master by adding the label "node-role.kubernetes.io/master=''"32.  [markmaster] Marking the node k8s-master001 as master by adding the taints [node-role.kubernetes.io/master:NoSchedule]33.  [patchnode] Uploading the CRI Socket information "/var/run/dockershim.sock" to the Node API object "k8s-master001" as an annotation34.  [bootstraptoken] using token: 8kjvh8.jc3kjgjepz06ptxl35.  [bootstraptoken] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials36.  [bootstraptoken] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token37.  [bootstraptoken] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster38.  [bootstraptoken] creating the "cluster-info" ConfigMap in the "kube-public" namespace39.  [addons] Applied essential addon: CoreDNS40.  [addons] Applied essential addon: kube-proxy42.  Your Kubernetes master has initialized successfully!44.  To start using your cluster, you need to run the following as a regular user:46.  mkdir -p $HOME/.kube47.  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config48.  sudo chown $(id -u):$(id -g) $HOME/.kube/config50.  You should now deploy a pod network to the cluster.51.  Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:52.  https://kubernetes.io/docs/concepts/cluster-administration/addons/54.  You can now join any number of machines by running the following on each node55.  as root:57.  kubeadm join 192.168.91.128: --token 8kjvh8.jc3kjgjepz06ptxl --discovery-token-ca-cert-hash sha256:98ad46e571ba9ce4f759fb8e00a93bf992f43862af0efb2fc544bc881eb8e192

出现 Your Kubernetes master has initialized successfully! 就表示成功了

查看 / etc/kube-server-key 文件,就是刚刚输出的内容

添加 Nodrport 端口范围

添加端口范围 1000-62000

1.  line_conf=`cat /etc/kubernetes/manifests/kube-apiserver.yaml|grep -n "allow-privileged=true"|cut -f  -d ":"`2.  sed -i -e "$line_conf"i'\    - --service-node-port-range=1000-62000' /etc/kubernetes/manifests/kube-apiserver.yaml

line_conf 的执行结果是 18,下面 sed 的意思就是,在 18 行之前添加指定内容

apiserver 绑定主机的非安全端口,这里绑定的是主节点 IP

1.  line_conf=`grep -n "insecure-port" /etc/kubernetes/manifests/kube-apiserver.yaml|awk -F ":" '{print $1}'`2.  sed -i -e "$line_conf"i"\    - --insecure-bind-address=192.168.91.128" /etc/kubernetes/manifests/kube-apiserver.yaml

line_conf 的执行结果是 25,下面 sed 的意思就是,在 18 行之前添加指定内容

apiserver 绑定主机的非安全端口号,默认为 8080

1.  sed -i -e 's?insecure-port=0?insecure-port=8080?g' /etc/kubernetes/manifests/kube-apiserver.yaml

sed 的意思就是,将 insecure-port=0 替换为 insecure-port=8080

设置 kubectl 权限

1.  mkdir -p $HOME/.kube2.  sudo cp -f /etc/kubernetes/admin.conf $HOME/.kube/config3.  sudo chown $(id -u):$(id -g) $HOME/.kube/config

这里的 $HOME 指的就是当前登录用户的宿主目录,也就是 / root

部署 CalICO 网络插件

修改 etcd 端点的 IP

1.  line=`grep "etcd_endpoints:" -n k8s-1.11/calico.yaml | cut -f  -d ":"`2.  sed -i "$line c \ \ etcd_endpoints: \"http://192.168.91.129:2379\"" k8s-1.11/calico.yaml

line 的执行结果是 17,$line 后面的 c 表示用新文本替换当前行中的文本

修改 CIDR

Kubernetes 集群中 service 的虚拟 IP 地址范围,以 CIDR 表示,该 IP 范围不能与物理机的真实 IP 段有重合。

将 192.168.0.0 替换为 192.138.0.0

1.  sed -i -e 's/192.168.0.0/192.138.0.0/g' k8s-1.11/calico.yaml

将 quay.io 修改为私有库地址

1.  sed -i -e "s?quay.io?192.168.91.131:5000?g" k8s-1.11/calico.yaml

除了 Kube DNS,它需要一个网络插件

1.  kubectl --kubeconfig=/etc/kubernetes/admin.conf apply -f k8s-1.11/calico.yaml

Kubernetes node 配置

还是在主节点操作,编写脚本

client.sh

1.  #!/bin/bash3.  # 安装组件4.  sudo apt-get update5.  sudo apt-get install -y docker.io ipvsadm --allow-unauthenticated6.  sudo apt-get install -y ebtables socat --allow-unauthenticated8.  # 关闭swap9.  sudo swapoff -a10.  fswap=`cat /etc/fstab |grep swap|awk '{print $1}'`11.  for i in $fswap;do12.  sudo sed -i "s?$i?#$i?g" /etc/fstab13.  done15.  # 手动加载IPVS的基本模块16.  sudo modprobe ip_vs17.  sudo modprobe ip_vs_rr18.  sudo modprobe ip_vs_sh19.  sudo modprobe ip_vs_wrr21.  # 安装deb软件包22.  sudo dpkg -i k8s-1.11/cri-tools*.deb23.  sudo dpkg -i k8s-1.11/kubernetes-cni*.deb24.  sudo dpkg -i k8s-1.11/kubelet*.deb25.  sudo dpkg -i k8s-1.11/kubectl*.deb26.  sudo dpkg -i k8s-1.11/kubeadm*.deb28.  # 开启cadvisor29.  sudo sed -i 's?config.yaml?config.yaml --cadvisor-port=4194?g' /etc/systemd/system/kubelet.service.d/-kubeadm.conf31.  # 添加cgroup驱动程序32.  sudo sed -i 8i'Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=cgroupfs"' /etc/systemd/system/kubelet.service.d/-kubeadm.conf34.  # 重新应用配置35.  sudo systemctl daemon-reload37.  # 导入k8s镜像38.  for i in k8s-1.11/*.tar.gz; do sudo docker load < $i; done39.  # 停止kubelet40.  sudo systemctl enable kubelet.service41.  sudo systemctl stop kubelet.service42.  # 重置k8s集群43.  sudo kubeadm reset -f45.  # 新增集群集工作节点的命令

将新增集群集工作节点的命令,写入到 client.sh

1.  echo "`tail -n2 /etc/kube-server-key`" >> client.sh

执行 echo 之后,那么 client.sh 的完整内容为:

1.  #!/bin/bash3.  # 安装组件4.  sudo apt-get update5.  sudo apt-get install -y docker.io ipvsadm --allow-unauthenticated6.  sudo apt-get install -y ebtables socat --allow-unauthenticated8.  # 关闭swap9.  sudo swapoff -a10.  fswap=`cat /etc/fstab |grep swap|awk '{print $1}'`11.  for i in $fswap;do12.  sudo sed -i "s?$i?#$i?g" /etc/fstab13.  done15.  # 手动加载IPVS的基本模块16.  sudo modprobe ip_vs17.  sudo modprobe ip_vs_rr18.  sudo modprobe ip_vs_sh19.  sudo modprobe ip_vs_wrr21.  # 安装deb软件包22.  sudo dpkg -i k8s-1.11/cri-tools*.deb23.  sudo dpkg -i k8s-1.11/kubernetes-cni*.deb24.  sudo dpkg -i k8s-1.11/kubelet*.deb25.  sudo dpkg -i k8s-1.11/kubectl*.deb26.  sudo dpkg -i k8s-1.11/kubeadm*.deb28.  # 开启cadvisor29.  sudo sed -i 's?config.yaml?config.yaml --cadvisor-port=4194?g' /etc/systemd/system/kubelet.service.d/-kubeadm.conf31.  # 添加cgroup驱动程序32.  sudo sed -i 8i'Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=cgroupfs"' /etc/systemd/system/kubelet.service.d/-kubeadm.conf34.  # 重新应用配置35.  sudo systemctl daemon-reload37.  # 导入k8s镜像38.  for i in k8s-1.11/*.tar.gz; do sudo docker load < $i; done39.  # 停止kubelet40.  sudo systemctl enable kubelet.service41.  sudo systemctl stop kubelet.service42.  # 重置k8s集群43.  sudo kubeadm reset -f45.  # 新增集群集工作节点的命令46.  sudo   kubeadm join 192.168.91.128:6443 --token bei68w.iovq9kr5w0kwcet3 --discovery-token-ca-cert-hash sha256:9ecbd6024fd9c66beee434cf277a69cfa2b325f4bcbf96d11e91a2a1f896fd62

远程执行客户端脚本

编写 install_client.sh 脚本

1.  #!/bin/bash3.  # node节点的IP地址4.  minions="192.168.91.129 192.168.91.131"6.  for i in $minions; do7.  # 复制软件包8.  scp -r k8s-1.11/ $i:/$HOME/9.  # 复制daemon.json10.  ssh $i sudo mkdir -p /etc/docker11.  scp /etc/docker/daemon.json $i:/$HOME/daemon.json12.  ssh $i sudo cp /$HOME/daemon.json /etc/docker/daemon.json13.  ssh $i sudo rm -f /$HOME/daemon.json14.  # 复制cilent.sh15.  scp client.sh $i:/$HOME/16.  # node节点执行client.sh17.  ssh $i sudo bash /$HOME/client.sh18.  done19.  echo 'please check kubenetes DNS server is runing or not ......'20.  echo 'command: kubectl get po -n kube-system|grep dns'

执行脚本

1.  bash install_client.sh

查看 k8s 的 DNS 服务状态

1.  root@k8s-master001:~# kubectl get po -n kube-system|grep dns2.  coredns-78fcdf6894-9cmnz                   /       ContainerCreating             3h3.  coredns-78fcdf6894-zs6zb                   /       ContainerCreating             3h

等待 5 秒,查看集群中的节点

1.  root@k8s-master001:~# kubectl get nodes2.  NAME            STATUS    ROLES     AGE       VERSION3.  k8s-master001   Ready     master    3h        v1.11.24.  k8s-node001     Ready     <none>    27m       v1.11.25.  k8s-node002     Ready     <none>    27m       v1.11.2

如果状态都是 Ready,表示正常!

三、一键部署脚本

请确保已经满足了 上面说的环境准备条件

k8s-v1.11.sh

1.  #!/bin/bash2.  set -e4.  # 运行前置条件5.  # 请确保主节点能ssh免密登录从节点。所有服务器,主要使用root用户操作6.  # 确保etcd已经部署好,节点数量为奇数,运行正常7.  # 确保docker私有仓库运行正常8.  # 确保所有服务器的时间一致9.  # 确保所有服务器已经安装好docker服务,并且已经修改了/etc/docker/daemon.json,能够正常推送到私有仓库10.  # 本脚本只能在主节点操作11.  # 具体操作,请参考链接:https://www.cnblogs.com/xiao987334176/articles/9947548.html13.  ##########################################################################14.  #                         INPUT15.  ##########################################################################17.  #setting kubernets master18.  while true19.  do20.  if [ "$masterIP" == "" ]; then21.  echo '请输入k8s主节点ip'22.  echo -e "K8S_MASTER_IP=\c"23.  read masterIP24.  else25.  break26.  fi27.  done28.  #setting docker registry29.  echo '请输入docker私有仓库ip,默认端口是5000'30.  echo '如果端口不是5000,请输入ip:端口,比如: 192.168.0.50:8888'31.  echo -e "dockerREG=\c"32.  read dockerREG33.  echo '请输入etcd服务器ip'34.  echo '如果有多个,用空格隔开。比如:"192.168.0.100 192.168.0.101 192.168.0.102"'35.  echo -e "ETCD_Severs=\c"36.  read ETCD_Server38.  #setting minions39.  while true40.  do41.  if [ "$k8minions" == "" ]; then42.  echo '请输入k8s从节点ip'43.  echo '如果有多个,用空格隔开。比如:"192.168.0.100 192.168.0.101 192.168.0.102"'44.  echo -e "minions=\c"45.  read k8minions46.  else47.  break48.  fi49.  done50.  ######################################################################################51.  #                                 Settings52.  ######################################################################################53.  # 判断etcd的ip变量54.  if [ "$ETCD_Server" == "" ];then55.  EXTERNAL_ETCD_ENDPOINTS=""56.  else57.  EXTERNAL_ETCD_ENDPOINTS=""58.  for i in $ETCD_Server;do59.  EXTERNAL_ETCD_ENDPOINTS="http://$i:2379,$EXTERNAL_ETCD_ENDPOINTS"60.  done61.  EXTERNAL_ETCD_ENDPOINTS=${EXTERNAL_ETCD_ENDPOINTS%?}62.  fi64.  # 判断docker仓库ip65.  if [ "$dockerREG" == "" ];then66.  dockerREG="$masterIP:5000"67.  else68.  if [ `echo $dockerREG|grep ":"|wc -l` -eq  ];then69.  dockerREG="$dockerREG:5000"70.  fi71.  fi73.  MASTERIP="$masterIP"74.  REPO=`echo $dockerREG | cut -d ":" -f `75.  K8S_MASTER_IP="$MASTERIP"76.  minions="$k8minions"78.  echo "REPO=$REPO"79.  echo "K8S_MASTER_IP=$MASTERIP"80.  echo "DOCKERREG=$dockerREG"81.  echo "minions=$k8minions"82.  echo "etcds=$EXTERNAL_ETCD_ENDPOINTS"83.  ######################################################################################84.  #                                 正式安装85.  ######################################################################################86.  # 复制软件包87.  scp -r $REPO:/repo/k8s-1.11 ./89.  # 安装相关组件90.  apt-get install -y docker.io ipvsadm ebtables socat --allow-unauthenticated92.  # 安装k8s的deb包93.  dpkg -i k8s-1.11/*.deb95.  # 开启cadvisor96.  sed -i 's?config.yaml?config.yaml --cadvisor-port=4194?g' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf98.  # 添加cgroup驱动程序99.  sed -i 8i'Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=cgroupfs"' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf101.  # 重新应用配置102.  systemctl daemon-reload104.  # 导入k8s镜像105.  for i in k8s-1.11/*.gz; do sudo docker load < $i; done107.  # 将包含quay.io镜像推送到私有仓库108.  # 查询包含calico的镜像109.  CalicoPro=$(sudo docker images|grep quay.io|awk -F 'quay.io/' '{print $2}'|awk '{print $1}'|sort|uniq)110.  for i in $CalicoPro;do111.  # 查询镜像的tag版本112.  Proversion=$(docker images|grep quay.io|grep $i|awk '{print $2}')113.  for j in $Proversion;do114.  # 打tag并推送镜像到私有仓库115.  sudo docker tag quay.io/$i:$j $dockerREG/$i:$j116.  sudo docker push $dockerREG/$i:$j117.  done118.  done120.  # 暂时关闭kubelet121.  # 重新设置kubelet服务开机启动122.  systemctl enable kubelet.service123.  # 停止kubelet服务124.  systemctl stop kubelet.service126.  # 关闭swap127.  swapoff -a128.  fswap=`cat /etc/fstab |grep swap|awk '{print $1}'`129.  for i in $fswap;do130.  sed -i "s?$i?#$i?g" /etc/fstab131.  done133.  # 删除默认的k8s文件134.  rm -rf /etc/kubernetes/*135.  rm -rf /var/lib/kubelet/*137.  # 重置k8s集群138.  kubeadm reset -f140.  # k8s临时配置文件141.  cat > /tmp/kubeadm-conf.yaml <<EOF142.  apiVersion: kubeadm.k8s.io/v1alpha1143.  kind: MasterConfiguration144.  networking:145.  podSubnet: 192.138.0.0/16146.  #apiServerCertSANs:147.  #- master01148.  #- master02149.  #- master03150.  #- 172.16.2.1151.  #- 172.16.2.2152.  #- 172.16.2.3153.  #- 172.16.2.100154.  etcd:155.  endpoints:156.  #token: 67e411.zc3617bb21ad7ee3157.  kubernetesVersion: v1.11.2158.  api:159.  advertiseAddress: $masterIP161.  EOF163.  # 将etcd添加到/tmp/kubeadm-conf.yaml164.  for i in `echo $EXTERNAL_ETCD_ENDPOINTS|sed 's?,? ?g'`;do165.  sudo sed -i "15i\  - $i" /tmp/kubeadm-conf.yaml166.  done168.  # 初始化集群169.  # 使用kubeadm init初始化集群170.  kubeadm init --config=/tmp/kubeadm-conf.yaml| sudo tee /etc/kube-server-key172.  # 添加Nodrport端口范围173.  # 添加端口范围1000-62000174.  line_conf=`cat /etc/kubernetes/manifests/kube-apiserver.yaml|grep -n "allow-privileged=true"|cut -f 1 -d ":"`175.  sed -i -e "$line_conf"i'\    - --service-node-port-range=1000-62000' /etc/kubernetes/manifests/kube-apiserver.yaml177.  # apiserver绑定主机的非安全端口,这里绑定的是主节点IP178.  line_conf=`grep -n "insecure-port" /etc/kubernetes/manifests/kube-apiserver.yaml|awk -F ":" '{print $1}'`179.  sed -i -e "$line_conf"i"\    - --insecure-bind-address=$masterIP" /etc/kubernetes/manifests/kube-apiserver.yaml181.  # apiserver绑定主机的非安全端口号,默认为8080182.  sed -i -e 's?insecure-port=0?insecure-port=8080?g' /etc/kubernetes/manifests/kube-apiserver.yaml184.  # 设置kubectl权限,$HOME是内置变量,表示宿主目录185.  mkdir -p $HOME/.kube186.  sudo cp -f /etc/kubernetes/admin.conf $HOME/.kube/config187.  sudo chown $(id -u):$(id -g) $HOME/.kube/config189.  # 部署CalICO网络插件190.  # 修改etcd端点的IP191.  line=`grep "etcd_endpoints:" -n k8s-1.11/calico.yaml | cut -f 1 -d ":"`192.  sed -i "$line c \ \ etcd_endpoints: \"$EXTERNAL_ETCD_ENDPOINTS\"" k8s-1.11/calico.yaml194.  # 修改CIDR195.  # 将192.168.0.0替换为192.138.0.0196.  sed -i -e 's/192.168.0.0/192.138.0.0/g' k8s-1.11/calico.yaml197.  #将quay.io修改为私有库地址198.  sed -i -e "s?quay.io?$dockerREG?g" k8s-1.11/calico.yaml200.  # 等待15秒201.  sleep 15202.  # 除了Kube DNS,它需要一个网络插件203.  kubectl --kubeconfig=/etc/kubernetes/admin.conf apply -f k8s-1.11/calico.yaml205.  # Kubernetes node配置206.  cat >client.sh <<EOF207.  # 安装组件208.  sudo apt-get update209.  sudo apt-get install -y docker.io ipvsadm --allow-unauthenticated210.  sudo apt-get install -y ebtables socat --allow-unauthenticated212.  # 关闭swap213.  sudo swapoff -a214.  fswap=\`cat /etc/fstab |grep swap|awk '{print \$1}'\`215.  for i in \$fswap;do216.  sudo sed -i "s?\$i?#\$i?g" /etc/fstab217.  done219.  # 手动加载IPVS的基本模块220.  Dline=\`sudo grep -n LimitNOFILE /lib/systemd/system/docker.service|cut -f 1 -d ":" \`221.  sudo sed -i "\$Dline c\LimitNOFILE=1048576" /lib/systemd/system/docker.service222.  sudo systemctl restart docker223.  if [ \`dpkg -l|grep kube|wc -l\` -ne 0 ];then224.  sudo apt purge -y \`dpkg -l|grep kube|awk '{print \$2}'\`225.  fi227.  # 安装deb软件包228.  sudo modprobe ip_vs229.  sudo modprobe ip_vs_rr230.  sudo modprobe ip_vs_sh231.  sudo modprobe ip_vs_wrr232.  sudo dpkg -i k8s-1.11/cri-tools*.deb233.  sudo dpkg -i k8s-1.11/kubernetes-cni*.deb234.  sudo dpkg -i k8s-1.11/kubelet*.deb235.  sudo dpkg -i k8s-1.11/kubectl*.deb236.  sudo dpkg -i k8s-1.11/kubeadm*.deb238.  # 开启cadvisor239.  sudo sed -i 's?config.yaml?config.yaml --cadvisor-port=4194?g' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf240.  if [ \`cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf|grep cgroup-driver|wc -l\` -eq 0 ];then241.  # 添加cgroup驱动程序242.  sudo sed -i 8i'Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=cgroupfs"' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf243.  sudo sed -i "s?\`tail -n1 /etc/systemd/system/kubelet.service.d/10-kubeadm.conf\`?& \$KUBELET_CGROUP_ARGS?g" /etc/systemd/system/kubelet.service.d/10-kubeadm.conf244.  fi245.  # 重新应用配置246.  sudo systemctl daemon-reload248.  # 导入k8s镜像249.  for i in k8s-1.11/*.tar.gz; do sudo docker load < \$i; done250.  # 停止kubelet251.  sudo systemctl enable kubelet.service252.  sudo systemctl stop kubelet.service253.  # 重置k8s集群254.  sudo kubeadm reset -f255.  # 新增集群集工作节点的命令256.  EOF258.  # 新增集群集工作节点的命令,追加到最后一行259.  sudo echo "sudo `tail -n2 /etc/kube-server-key`" >> client.sh261.  # 安装客户端262.  for i in $minions; do263.  # 复制软件包264.  scp -r k8s-1.11/ $i:/$HOME/265.  # 复制daemon.json266.  ssh $i sudo mkdir -p /etc/docker267.  scp /etc/docker/daemon.json $i:/$HOME/daemon.json268.  ssh $i sudo cp /$HOME/daemon.json /etc/docker/daemon.json269.  ssh $i sudo rm -f /$HOME/daemon.json270.  # 复制cilent.sh271.  scp client.sh $i:/$HOME/272.  # node节点执行client.sh273.  ssh $i sudo bash /$HOME/client.sh274.  done275.  echo 'please check kubenetes DNS server is runing or not ......'276.  echo 'command: kubectl get po -n kube-system|grep dns'278.  # 查看k8s的DNS服务状态279.  kubectl get po -n kube-system|grep dns280.  # 睡眠25秒281.  sleep 25282.  # 查看集群中的节点283.  kubectl get nodes

运行之前,查看 etcd 的状态

1.  root@k8s-master001:~# curl http://192.168.91.129:2379/version -s | python3 -m json.tool2.  {3.  "etcdserver": "3.3.10",4.  "etcdcluster": "3.3.0"5.  }

查看 docker 私有仓库的状态

1.  root@k8s-master001:~# curl http://192.168.91.131:5000/v2/_catalog -s | python3 -m json.tool2.  {3.  "repositories": [4.  "calico/cni",5.  "calico/kube-controllers",6.  "calico/node"7.  ]8.  }

登录到 docker 私有仓库服务器,查看 / repo 目录

1.  root@k8s-node002:~# ll /repo/2.  total3.  drwxr-xr-x   root root  Nov  : ./4.  drwxr-xr-x  root root  Nov  : ../5.  drwxr-xr-x   root root  Nov  : k8s-1.11/

正式运行脚本

1.  bash k8s-v1..sh

输入如下:

1.  请输入k8s主节点ip2.  K8S_MASTER_IP=192.168.91.1283.  请输入docker私有仓库ip,默认端口是50004.  如果端口不是5000,请输入ip:端口,比如: 192.168.0.50:5.  dockerREG=192.168.91.1316.  请输入etcd服务器ip7.  如果有多个,用空格隔开。比如:"192.168.0.100 192.168.0.101 192.168.0.102"8.  ETCD_Severs=192.168.91.1299.  请输入k8s从节点ip10.  如果有多个,用空格隔开。比如:"192.168.0.100 192.168.0.101 192.168.0.102"11.  minions=192.168.91.129 192.168.91.13113.  中间输出略....15.  NAME            STATUS    ROLES     AGE       VERSION16.  k8s-master001   Ready     master    4m        v1.11.217.  k8s-node001     Ready     <none>    2m        v1.11.218.  k8s-node002     Ready     <none>    1m        v1.11.2

上面的红色部分,请根据环境需求填写。

末尾的 k8s 节点状态都是 Ready,表示安装成功了!

查看所有命名空间

1.  root@k8s-master001:~# kubectl get ds --all-namespaces2.  NAMESPACE     NAME          DESIRED   CURRENT   READY     UP-TO-DATE   AVAILABLE   NODE SELECTOR                   AGE3.  kube-system   calico-node                                                     <none>                          8m4.  kube-system   kube-proxy                                                      beta.kubernetes.io/arch=amd64   8m

查看 calico 网络状态

1.  kubectl get pods -o wide -n kube-system | grep calico-node

确保都是 Running 状态

至此 k8s,安装就完成了!

本文参考链接:

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

来源链接:https://www.shuzhiduo.com/A/A7zgqPwl54/

Kubernetes 概述和搭建 (多节点)相关推荐

  1. 全手动搭建Kubernetes集群——Master管理节点和Node工作节点部署

    目录 前言 一.Master管理节点需要安装的组件介绍 二.配置Master管理节点各组件模块 1.配置kube-apiserver组件 2.配置kube-controller-manager组件 3 ...

  2. 阿里云Kubernetes实战2–搭建基础服务

    前言: 在系列的第一篇文章中,我已经介绍过如何在阿里云基于kubeasz搭建K8S集群,通过在K8S上部署gitlab并暴露至集群外来演示服务部署与发现的流程.文章写于4月,忙碌了小半年后,我才有时间 ...

  3. kubernetes集群搭建以及遇到的问题

    from:kubernetes集群搭建以及遇到的问题 centos7.2搭建kubernetes集群以及遇到的问题 环境准备: centos7.2 etcd flannel kubenetes1.3 ...

  4. Kubernetes集群搭建之Etcd集群配置篇

    docker快速启动etcd脚本 https://www.cnblogs.com/ka1em/p/11300355.html rm -rf /tmp/etcd-data.tmp && ...

  5. kubernetes集群搭建Zabbix监控平台

    kubernetes集群搭建Zabbix监控平台 一.zabbix介绍 1.zabbix简介 2.zabbix特点 3.zabbix的主要功能 4.zabbix架构图 二.检查本地k8s环境 1.检查 ...

  6. 【Docker之Swarm详细讲解Swarm集群搭建管理节点工作节点Raft一致性协议overlay网络Docker结合Swarm部署WordPress个人博客实战】

    一.知识回顾 之前的内容都帮你整理好了,在这里哟! [0.Docker相关目录文章整理,可自行查看,包含多节内容] [1.Docker详细安装部署&阿里镜像地址配置] [2.Docker架构& ...

  7. mysql pxc集群介绍_PXC集群的概述及搭建

    PXC集群的概述及搭建 PXC集群的简介 Percona XtraDB Cluster(下文简称PXC集群)提供了MySQL高可用的一种实现方法.PXC集群以节点组成(推荐至少3节点,便于故障恢复,后 ...

  8. (硅谷课堂项目)Java开发笔记2:项目概述,搭建项目环境和开发讲师管理接口

    文章目录 (硅谷课堂项目)Java开发笔记2:项目概述,搭建项目环境和开发讲师管理接口 1.项目概述 1.1 项目介绍 1.2 硅谷课程流程图 1.3 硅谷课堂功能架构 1.4 硅谷课堂技术架构 1. ...

  9. Kubernetes集群搭建及容器化部署

    Kubernetes集群搭建及容器化部署 目录 一.k8s 集群部署 2 1.k8s 快速入门 2 2.k8s 集群安装 10 二.k8s 容器化部署 18 1.Kubectl命令行部署 18 2.K ...

最新文章

  1. lodop+art-template实现web端漂亮的小票样式打印
  2. Win10 配置 TensorFlow-gpu 深度学系框架
  3. 【转】ABP源码分析八:Logger集成
  4. 完整的金融类APP UI设计素材,深度学习临摹
  5. python ftp 文件修改时间 乐贴_如何使用Python ftplib获取FTP文件的修改时间
  6. JS基础知识(数据类型)
  7. 求二叉树左右子树高度差_LeetCode刷题实战110:平衡二叉树
  8. 互联网行业的颜值担当,李彦宏!
  9. android 车牌字符分割,车牌识别 之 字符分割
  10. 安装装ankhsvn
  11. ui-grid 使用讲解
  12. php多合一安装包,DOXCX多合一小程序系统Sass平台源码分享
  13. 5G:智能座舱的分水岭,蔚来小鹏们的翻身战
  14. 新增诊所19804家 | 私营诊所要如何主动?才能被患者选择
  15. Linux 操作系统
  16. Python3的fo if while 循环
  17. leetcode 876.链表中间结点
  18. Unity基础笔记(3)—— Unity UI系统
  19. VC#2005进行WPS表格2005二次开发的例子
  20. jstack命令(Java Stack Trace)

热门文章

  1. 瑞企体育系统源码,赛事直播系统,足球直播程序,体育赛事足球系统功能介绍
  2. {转发}尚硅谷资料集锦
  3. AD19——双面PCB快速铺铜
  4. java并发-ReentrantReadWriteLock读写锁
  5. php二手房系统,phpwind房产新版上线 抢先体验二手房新功能
  6. 在安卓中实现Zigbee串口设备采集模块
  7. php 国外手机号,国内外手机号码正则表达式
  8. python 文件夹下所有文件_使用Python遍历文件夹下所有文件(包所有含子文件夹)...
  9. 元宇宙电商|“NFG”是什么,企业该如何利用元宇宙实现增值呢?
  10. Mac中删除docker镜像