k8s二进制方式安装

基础知识

基本概念

名词含义解释
pod一个宿主机中可以有多个pod(豌豆荚)是k8s中最小的运行单元,都会被分配一个ip;类似为一个docker中的一个容器
pod控制器监控pod的运行,其下可以运行多个 pod;如果其下的pod被删除,pod控制器会重新启动一个新的;两种kind,daemon set、deployments、
name资源名称k8s中所有的所有功能被称为资源:资源的配置信息有:api版本(apiVersion)类别(kind),元数据(metadata),定义清单(spec),状态(status)等;而资源名称就在metadata中存储;同一名称空间下的资源名称唯一;k8s中一切皆资源
namespace名称空间为了隔离k8s中的各种资源;将k8s内部的资源划分为虚拟集群组;默认的名称有default、kube-system、kube-public;查询k8s中特定的资源需要带上相应的名称空间
Label标签资源和标签多对多关系;定义标签:key=value
标签过滤器过滤选择带有特定标签的资源过滤方式有:等于、不等于、属于、不属于、存在
Service一组提供相同服务的pod对外提供的接口;仅提供流量调度用于解决pod销毁,ip消失的问题;Request----->Ingress---->Service---->pod
IngressOSI第七层的应用,对外暴露接口调度不同业务域,不同URL访问路径的流量
secret资源秘钥资源分为3种,generate(通用,token)、docker_register(自定义json格式)、TLS

组成

名词含义解释
配置存储中心etcd服务存储集群中各个节点的元数据信息;类似一个非关系型数据库
master主控节点(一个宿主机)1. kebu-apiserver 2. kebu-controller-manager 3.kube-scheduler
kebu-apiserverk8s大脑1. 提供了集群管理的REST-API接口(包括鉴权、数据校验和集群状态变更)2. 负责其他模块数据的交互,提供数据枢纽的功能; 3. 资源配额控制的入口 4.提供完备的资源安全机制
kebu-controller-manager控制及管理器由一系列的控制器组成;通过apiserver来控制整个集群的状态并确保集群出于预期的状态下
kube-scheduler资源调度器接受指令并调度pod到合适的节点上;预选策略和优选策略
node运算节点(一个宿主机)主要包括kube-letkube-proxy
kube-let节点大脑1. 定时从某个地方获取pod的运行状态(那个容器、副本数、网络、存储配置等等)调用对应的容器平台接口到达这个状态;2. 定时汇报当前pod的状态给apiserver,以方便后续的调度 3. 定时清理容器和镜像资源,保证推出的容器不会占用太多资源
kebu-proxy每个节点上的网络代理;维护了一套虚拟集群网络1. 建立了集群网络和pod网络的关系;三种流量调度模式,推荐使用ipvs(基于LVS) 2. 依据kebu-apiserver建立更新删除调度规则,并通知kebu-apiserver自己的变更
LVS内网映射到外网的一种方式网络拓扑 客户端请求 -->vip服务–负载均衡–>真实服务器–>响应数据–直接–>客户端;优点:请求经过vip服务,响应直接返回给客户端,避免vip服务成为网络瓶颈

集群中的网络设计

在这里插入图片描述

网络含义解释
10.4.7.21节点网络其中4为哪个机房,7为哪个项目的测试项或正式线
172.7.21.0/24pod网络172打头,7.21继承宿主机的ip。方便排查问题
192.168.0.0Service网络通过kebu-proxy;利用k8s中特色的标签选择器,将cluster-ip对应多个相同服务的pod

部署准备工作

  • 基础设施
    • CentOS7.6系统(内核在3.8以上)
    • 关闭SELinux, 关闭firewalld服务
    • 时间同步(chronyd)
    • 调整Base源和Epel源
    • 内核优化

部署须知

  1. mini-kebu,单节点微型k8s,仅用于实验和练手
  2. 第一次部署推荐使用,二进制部署,因为都需要签ssl证书,证书有效期为1年,一年后过期时候需要知道哪个证书是哪个服务的
  3. 使用kebuadmin部署,k8s部署工具,跑在k8s容器里,部署简单

部署流程

  1. 准备2核2G虚拟机5台,节点网络ip为10.4.7.xx;
  2. 部署bind9域名服务
  3. 签CA证书,需要注意证书的过期时间(使用k8admin部署,ca证书默认为一年)

使用cfssl签发ssl证书

下载安装 cfssl、cfssl-json、cfssl-certinfo;并为其附加可执行的权限
cfssl :证书签发的主要工具
cfssl-json :将cfssl生成的证书( json格式)变为文件承载式证书
cfssl-certinfo :验证证书的信息

创建ca证书签名的请求(csr)json文件
CN: Common Name ,浏览器使用该字段验证网站是否合法, 一般写的是域名。非常重要。浏览器使用该字段验证网站是否合法
C: Country,国家ST:State,州,省L: Locality ,地区,城市O: Organization Name ,组织名称,公司名称OU: Organization Unit Name ,组织单位名称,公司部门

# 位于ca-csr.json
cd /opt/certs/
cat > ca-csr.json <<EOF
{
    "CN": "zoneyet",
    "hosts": [],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "ST": "henan",
            "O": "zhengzhou",
            "OU": "zoneyet"
        }
    ],
    "ca": {
        "expiry": "175200h"
    }
}
EOF

指定ca请求文件,生成json格式的证书证书 cfssl gencert -initca ca-csr.json
生成josn格式的证书之后转为文件承载形式的ca证书 cfssl gencert -initca ca-csr.json | cfssl-json -bare ca 生成 ca.pem(根证书), ca-key.pem(根证书的私钥)
cfssl-certinfo -cert 证书名称 查询证书的信息

harbor搭建私有镜像服务器

将本地的镜像使用tag命令打包之后,push到私有镜像服务器中,push之前需要使用docker log 命令登录到harbor服务中,用户名和密码和登录后台的用户名密码一致;成功之后可以在后台中看到harbor拥有的镜像;

开始部署

部署etcd服务(版本3.1)

etcd之间需要通信需要ssl,需要签发的证书
创建基于根证书的配置文件ca-config.json文件

 {
  "signing": {
    "default": {
      "expiry": "175200h"
    },
    "profiles": {
      "server": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth"
        ],
        "expiry": "175200h"
      }
      "client": {
        "usages": [
            "signing",
            "key encipherment",
            "client auth"
        ],
        "expiry": "175200h"
      }
      "peer": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ],
        "expiry": "175200h"
      }
    }
  }

创建etcd的ssl证书请求文件 其中hosts需要配上etcd需要通信的所有主机

{
    "CN": "etcd.zoneyet",
    "hosts": [], 
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "ST": "henan",
            "O": "zhengzhou",
            "OU": "zoneyet"
        }
    ],
    "ca": {
        "expiry": "175200h"
    }
}

使用cfssl gencert -config=co-config.json 命令生成证书文件
./etcd.sh一堆参数 进行启动,

命令含义解释
./etcdctl cluster-health来查询etcd配置集群中其他服务的状态
./etcdctl member list查询集群服务中的信息,ip是否是leader等

api-server启动

签发3套ssl证书,拷贝到下载的/opt/apiserver/certs/

  1. 作为etcd的客户端来与etcd通信
  2. 作为apiserver服务端,让别的客户端来建立链接
  3. ca.pem及ca-key.pem作用?

k8s资源配置清单,用户k8s日志审计,audit.yaml文件
运行起来之后,监听127.0.0.1:8080和:::6443
如果启用多个api-server服务可以使用nginx的stream命令的4层反向代理;如果nginx为集群可以使用keepalive来实现vip,漂移服务器的ip地址,实现服务的高可用;

controller-manager启动

指定master参数为本机的api-server;且使用的协议为http,不需要安装证书
可以指定管理的容器的ip地址范围

scheduler启动

指定master参数为本机的api-server;且使用的协议为http,不需要安装证书

集群命令含义解释
kubectl get cs来查询配置集群中其他服务的状态
kubectl get node来查询配置集群中计算节点的状态
kubectl get pods来查询配置集群中计算节点的状态
kubectl create -f nginx-ds.yaml通过yaml文件 创建nginx服务
kubectl label node ip或主机名 指定角色指定节点的标签

kuberlet部署

给kuberlet签发cfssl证书

  1. 配置文件kubelet.kubeconfig集成ca证书 kubectl config set-cluster myk8s --certificate=ca.pem绝对路径 --embed-cert=true --server=apiserver地址 --kubeconfig=kubelet.kubeconfig
  2. 配置文件kubelet.kubeconfig集成client证书 kubectl config set-credentials k8s-node --certificate=ca.pem绝对路径 --embed-cert=true --kubeconfig=kubelet.kubeconfig
  3. 配置文件kubelet.kubeconfig添加集群名称和用户名 kubectl config set-context myk8s-context --cluster=myk8s --user=k8s-node -- kubeconfig=kubelet.kubeconfig

切换k8s上下文kubectl config use-context myk8s-context --kubeconfig=kubelet.kubeconfig???

kubectl create -f k8s-node.yaml 创建k8s资源;会记录在etcd数据库中
配置k8s-node.yaml文件?定义一个k8s-node用户让其具有system:node的集群权限(目标让k8s用户在集群中具有运算节节点的权限)
kubectl get clusterrolebinding k8s-node -o yaml 查询名称为k8s-node资源的权限绑定信息

docker pull kuber/pause 该镜像用于初始化docker容器的网络空间、ups空间

kube-proxy部署

签发ssl证书,创建kube-proxy.kubeconfig文件
kips:

  1. 如果证书的CN使用"system:kube-proxy"(在k8s中为默认的proxy角色),签证书的时候直接指定user=kube-proxy,那么不需要绑定该服务或节点的角色,会自动绑定;
  2. 使用 kubectl config 创建kube-proxy.kubeconfig文件

启动ip_vs模块

  1. 启动proxy服务时候分发网络使用,ip_vs的nq调度方法,调度算法只能使用rr(轮询调度)

启动kube-proxy
指定hostname;proxy_mode,ipvs-scheduler;及创建的配置文件
ipvsadm -Ln 查询本机的ipvs规则

资源控制清单

  • 资源类型有 pod控制器(pods、deployment)、pod(deploy)、service网络(svc)、历史修改记录(describe);如果不指定资源名称那么获取该空间下的所有该类型资源
  • 陈述式,直接指定资源名称及空间名称;声明式,指定yaml文件
集群命令含义解释
kubectl get all -n 名称空间查询指定名称空间下所有资源,默认default空间下
kubectl get 资源类型 资源名称 -n 名称空间查询某个资源的信息-o wide表示输出扩展字段;-o yaml 表示以资源配置清单的方式导出配置文件;
kubectl explain 资源类型.资源属性查询某个资源属性的解释说明
kubectl create -f xxx.yaml通过yaml资源配置清单来声明式创建资源
kubectl apply -f xxx.yaml通过yaml资源配置清单来声明式修改资源配置清单在线修改,没有修改记录
kubectl edit -f xx.yaml通过yaml资源配置清单来声明式修改资源配置清单离线修改,有修改记录
kubectl describe describe 资源名称 -n namespace查询指定资源的历史修改记录

FLANNEL(CNI网络插件)

能使容器在不同宿主机之间的通信

安装下载flannel,建立软连接,拷贝client.pem及client-key.pem证书到flannel/certs目录下(因为其要与etcd通信)
vi subnet.env

FLANNEL_NETWORK=172.7.0.0/16  
FLANNEL_SUBNET=172.7.21.1/24
FLANNEL_MTU=1500
FLANNEL_IPMASQ=false

启动./flanneld,指定启动ip及port,etcd的ip,及与之通信的cert证书,subnetfile
flannel依赖与etcd进行配置的存储,需要在etcd中建立一个键值对 ./etcdctl set /coreos.com/netword/config '{"Netword": "172.7.0.0/16", "Backend": {"Type": "host-gw"}}'
创建supervisord配置文件,启动flannel;
如果网络类型为host-gw类型,那么flannel就是在本地添加了几条静态路由记录,先从本宿主机以另外一个宿主机为网关访问的另外一个宿主机中的容器;可以通过 route -n 查询本地的路由命令查询宿主机中的所有静态路由;前提是两个宿主机可以直接通信,效率是最高的。
VxLAN 如果 /coreos.com/netword/config 网络配置为 ‘{“Netword”: “172.7.0.0/16”, “Backend”: {“Type”: “VxLAN”, “Directrouting”: true}}’;VxLAN模型为在两个宿主机之间建立一个网络隧道(创建两个可以互通的网卡),来实现两个宿主机的通信,进而实现两边容器的相互通信;该配置下,如果两个宿主机可以直接通信,那么会以host-gw模式运行,如果不同,以VxLAN模式运行
作用: 就是在宿主机中添加了一条route,在对面宿主机中删除iptables中的filter表中的reject动作;添加指定ip的filter表的accept动作

对网络的优化
发现另外一台宿主机中的获取的本宿主机的容器的请求地址,不是本容器的ip而是本宿主机的ip,这里是因为ip-tables的snet规则对源地址做了修改,为了能区分是哪个容器来的请求可以修改该条ip-tables的规则
iptables -t nat -I postrouting -s 172.7.21.0/24 ! -d 172.7.0.0/16 ! -o docker0 -j MASQUERADE 修改后的规则含义为:10.4.7.21主机上,来源是172.7.21.0/24段的网络(本宿主机容器),目标不是172.7.0.0/16(该机房所有宿主机容器),出网不是从docker0出来的做SNAT转换。避免容器之间来回进行地址转换

优化过程

  1. 安装iptables-services
  2. 删除iptables中两个reject规则;
  3. 修改snet规则,为上面的规则,避免容器之间通信的snat转发

服务发现Coredns

负责将Service资源的名字和service资源的Cluster-ip对应上(服务内部)
使用k8s官方的yaml文件来创建Coredns服务;一般创建在kube-system名称空间下
资源名称.命名空间名称.svc.cluster.local 在k8s集群内部,来访问对应的资源;集群外部并不能访问;
如果想使用短域名,需要配上search 域名结尾????
cat /etc/resolv.conf 查询dns配置文件

服务暴露Ingress

只能暴露7层应用,类似nginx的http功能;
常用的ingress控制器:traefik:1.7.2-alpinef

  1. 准备traefik镜像
  2. rbac.yaml traefik的鉴权模块
  3. traefik_ds.yaml的配置清单
    采用kind: Daemonset的方式部署,该方式下符合匹配条件的节点都会部署一个pod;如果有新节点加入集群时,也会为他们新增一个pod,当节点从集群中移除时,这些pod也会被移除
  4. svc.yaml traefik的Service资源
  5. traefik-web-ui.yaml Ingress资源
    Ingress资源配置清单,rules中配置了path及对应的服务,类似nginx
spec: 
   rules:
   - host: traefik.od.com  # 此处为traefik服务的域名
   	http: 
   		paths:
   			- path: /
   			backend: 
   				serviceName: hostname
   				servicePort: 8080
  1. 在对外服务的nginx配置中,模糊匹配url,*.od.com统一分发到ingress服务,然后经ingress代理到各个Service对应的服务;其外网对外的nginx还可以配置详细的url,用于卸载ssl,避免ingress使用https协议过于复杂;

/etc/ngixn/conf.d/*.od.com.conf

upstream default_backend_traefik {
	server 10.4.7.21:81		max_fails=3 fail_timeout=10s;
	server 10.4.7.22:81		max_fails=3 fail_timeout=10s;
}
server {
	server_name *.od.com;
	location / {
		proxy_pass	http://defult_backend_traefik;
		proxy_set_header	Host		$http_host;
	proxy_set_header		x-forwarded-for	$proxy_addx_forwarded_for;
	}
}

/etc/nginx/conf.d/dashboard.od.com.conf

server		{
listen 				80;
server_name 		dashboard.od.com;  # 详细域名
rewrite 			^(.*)$ https://${server_name}$1 permannet; # 重定向
}
server		{
	listen					443 ssl;
	server_name				dashboard.od.com; 
	
	ssl_certificate 			".crt文件路径";
	ssl_certificate_key 		".key文件路径";
	ssl_session_cache			shared:SSL:1m;
	ssl_session_timeout	10m;
	ssl_ciphers	HIGH:!aNULL:!MDS;
	ssl_prefer_server_ciphers	on;
	location /	{
		proxy_pass				http://default_backend_traefik;
		proxy_set_header		Host			$http_host;
		proxy_set_header		x-forwarded-for	$proxy_addx_forwarded_for;
	}
}

dashboard资源管理插件-仪表盘

  1. 准备dashboard:1.8.3的镜像
  2. 去k8s的github上找kubernetes/cluster/addons/dashboard 找rbac.yaml、dp.yaml、svc.yaml、ingress.yaml
    在bind9中创建一条dashboard.od.com ip的记录;
  3. 签发证书

rbac(k8s中的鉴权机制)

  • 权限
    - get write update list watch
  • 角色
    - Role 普通角色
    ClusterRole 对这个集群有效
  • 用户 通过绑定角色来获取权限
    - 用户账户 user;kubeconfig文件就是k8s中用户的一个配置文件
    服务账户 service account
    所有的pod都必须有一个用户
    过程
  1. 创建用户,声明类型,服务账户还是用户账户;声明用户名
  2. 创建角色
    声明角色名称
    声明角色具有的权限;rules: apiGroups(组),resources(资源),verbs(权限)
  3. 绑定用户和角色,roleRef 绑定的角色;subjects:绑定的用户

平滑升级集群

  1. 将nginx4层及7层的流量切断到该节点的流量
  2. 删除资源偏少的节点 kubectl delete node node_name;会自动迁移到其他节点查询k8s上的节点 kubectl get nodes
  3. 安装需要的安装包后,将配置文件和需要的文件移动到新的安装包里,重新启动服务;
  4. 切换nginx4层及7层的流量,重新流入新集群

共享存储

不使用persistent Volumes;而是使用 nfs

  1. 配置nfs共享服务
    yum install nfs-utils -y
    nfs配置文件
 ~]# cat /etc/exports
/data/nfs-volume 10.4.7.0/24(rw,no_root_squash)
mkdir -p /data/nfs-volume
systemctl start nfs
systemctl enable nfs

k8s配置清单中支持,nfs卷的加载

spec:
	volumes:
     - name: data
       nfs:  # nfs类型的卷
         server: hdss7-200
         path: /data/nfs-volume/jenkins_home
     - name: docker
       hostPath:  # 宿主机中的卷
         path: /run/docker.sock
         type: ''
    container:
    ...
		volumeMounts:
 		- name: data  # 在容器中使用卷
         mountPath: /var/jenkins_home  # 映射到容器中的位置

其他tips

  1. 实现容器中与宿主机的docker-service通信,只需要容器中安装docker-start,将宿主机中的/run/docker.socket映射到宿主机相同位置就可以和宿主机通信了;
  2. docker镜像拉取策略
    IfNotPresent 如果本地仓库没有就去远程仓库拉
  3. 如果想拉取habor中的私有仓库,需要在资源配置清单中配置上,ImagePullSecrects: -name: harbor (该名字为同一名称空间下的 secret名字)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

岳大博

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值