MariaDB修改最大连接数

1.mariadb数据库最大连接数,默认为151

MariaDB [(none)]> show variables like 'max_connections';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections |  151  |
+-----------------+-------+

2.配置/etc/my.cnf

[mysqld]下新添加一行如下参数:

max_connections=3000

systemctl restart mariadb 重启mariadb服务,再次查看mariadb数据库最大连接数,最大连接数是214,并非我们设置的3000。

MariaDB [(none)]> show variables like 'max_connections';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections |  214  |
+-----------------+-------+

由于mariadb有默认打开文件数限制

vi /usr/lib/systemd/system/mariadb.service

取消[Service]前的#号,
[Service]新添加两行如下参数:

LimitNOFILE=10000
LimitNPROC=10000

4.重新加载系统服务,并重启mariadb服务

systemctl --system daemon-reload
systemctl restart mariadb.service

再次查看mariadb数据库最大连接数,可以看到最大连接数已经是3000

MariaDB [(none)]> show variables like 'max_connections';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections | 3000  |

+-----------------+-------+

从数据库延迟同步主数据库;

Mysql (需5.6以上版本)延迟复制配置,通过设置Slave上的MASTER TO MASTER_DELAY参数实现:

CHANGE MASTER TO MASTER_DELAY = N; 

N为多少秒,该语句设置从数据库延时N秒后,再与主数据库进行数据同步复制

具体操作:

登陆到Slave数据库服务器

mysql>stop slave; 
mysql>CHANGE MASTER TO MASTER_DELAY = 600; 
mysql>start slave; 
mysql>show slave status G; 

查看SQL_Delay的值为600,表示设置成功。

注释:
SQL_Delay:一个非负整数,表示秒数,Slave滞后多少秒于master。
SQL_Remaining_Delay:当 Slave_SQL_Running_State 等待,直到MASTER_DELAY秒后,Master执行的事件,

此字段包含一个整数,表示有多少秒左右的延迟。在其他时候,这个字段是0。

【最新发布的MariaDB10.2.3支持延迟复制】

MariaDB修改编码格式

1、通过set修改value字段

2、登录MySQL,使用 show variables like ‘character%’;

3、查看当前编码格式

未分类

4、使用 set character_set_client = ‘utf8mb4’;

5、直接修改variable_name的value

未分类

Mariadb通过配置文件修改编码

1、登录MySQL,使用

SHOW VARIABLES LIKE 'character%';

查看当前使用的字符集,应该有好几个不是UTF-8格式。

2、要修改的配置文件位于 /etc/my.cnf.d目录下:

client.cnf

在[client]字段里加入

default-character-set=utf8

server.cnf

在[mysqld]字段里加入

character-set-server=utf8

systemctl restart mariadb 配置生效,修改后的效果如下:

未分类

3、修改字段编码格式:

4、use 库名

ALTER TABLE  表名 MODIFY `字段` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT '备注';

CentOS LVM卷转变成普通卷操作步骤

CentOS LVM卷转变成普通卷操作步骤

1.系统信息

lsb_release -a
LSB Version:    :core-4.1-amd64:core-4.1-noarch
Distributor ID: CentOS
Description:    CentOS Linux release 7.2.1511 (Core)
Release:    7.2.1511
Codename:   Core

2.背景

公司线上服务器要上线大数据平台,使用LVM卷对生产上业务有
一定的影响。新机器的部署我都是使用的自动化部署脚本进行的,
脚本中对数据盘使用的LVM格式,因此,我需要手动更改
磁盘卷的类型。

3.具体实施步骤

#操作前请做好数据的备份
#卸载逻辑卷之前的文件系统
df -h
文件系统                    容量  已用  可用 已用% 挂载点
/dev/mapper/vgdata-lvdata1  197G   61M  187G    1% /data
#umount文件系统
umount /data
#lvremove操作
lvremove /dev/vgdata/lvdata1
Do you really want to remove active logical volume vgdata/lvdata1? [y/n]: y
Logical volume "lvdata1" successfully removed
#vgremove操作
vgremove vgdata
Volume group "vgdata" successfully removed
#pvremove操作
pvremove /dev/vdb1
Labels on physical volume "/dev/vdb1" successfully wiped.
#fdisk磁盘分区
##查看下当前lvm的分区
fdisk -l
设备 Boot      Start         End      Blocks   Id  System
/dev/vdb1            2048   419430399   209714176   8e  Linux LVM
#重新进行磁盘分区
fdisk /dev/vdb
d --> p --> n --> 三次enter默认 --> p --> w
#对刚分好分区的磁盘格式化
mkfs.ext4 /dev/vdb1
#查看UUID
blkid
/dev/vdb1: UUID="456b88bf-19fe-4b80-b408-13451d10e78w" TYPE="ext4"
#更改/etc/fstab文件
sed -i 's#/dev/vgdata/lvdata1   /data    ext4    defaults        1 1 #UUID="456b88bf-19fe-4b80-b408-13451d10e78w"  /data                ext4    defaults        1 1#g'
#挂载分区
mount -a

kubernetes 与LVM的结合

本文主要介绍k8s与LVM结合使用的场景,在原生的k8s中对于本地存储提供了hostPath与emptyDir两种volme,hostPath是直接将文件存储在本地主机上,存在的问题是无法进行quota管理,单个用户就可能将所有的磁盘打满;在kubernetes 1.10 local ephemeral storage 成为beta版本,可以对emptyDir进行磁盘限制,但是这里的磁盘配额不仅包括用户写入epmtyDir的数据,也包括writable layer和logs,并且emptyDir会随着pod的删除而删除,无法自定义生命周期,如果应用程序需要在pod退出后保留这些数据,emptyDir就无法胜任了。鉴于k8s原生volume的以上特点无法满足复杂的业务需求,我们可以根据LVM提供一种本地存储的volume方案。本文只介绍LVM与k8s结合实现方式,具体LVM及k8s的知识请自行查阅相关资料。

Out-of-Tree Volume Plugins

k8s对于额外的存储提供良好的支持,参见 Out-of-Tree Volume Plugins, 有两种方式实现volume plugin: CSI和FlexVolume,第一种是现在官方推荐的方式,不过第二种官方还继续提供支持而且使用起来更加简单,官方提供了FelxVolme LVM shell版的简单实现,参见github地址,其实就是一个binary或脚本来提供特定的调用,对于LVM来说需要实现基本的mount和umount subcommand供kubelet回调。mount subcommand创建LVM,分为以下几个步骤:

  1. 调用lvcreate创建LVM设备,大小为用户在yaml文件中指定的磁盘大小,会在kubelet调用plugin的时候作为参数传递进来

  2. 调用mkfs格式化LVM为某种文件类型

  3. 创建挂载点目录,该参数一般都由plugin作为参数传递进来,一般就是$KUBELET_ROOT_DIR/pods/$POD_UID/volumes/…目录下

  4. mount LVM设备到挂载点上

  5. 汇报LVM VG的使用情况,因为后面调度pod的时候需要使用这些信息

上述是kubelet在回调plugin mount subcommand的操作,对于umount subcommand因为需要自定义删除策略,我们不能直接将LVM 删除掉,但挂载点目录必须删除掉,否则kubelet会认为该volume没有被正确移除,pod一直处于terminating无法删除,此时有种tricky的方式就是move挂载点目录,这样LVM正常mount到挂载点上,pods也可以正常被删除,至于后续的自定义删除策略就直接操作move之后的挂载点设备了。需要注意的是应用程序如果要查看退出pod的LVM中的数据必须去移动之后的挂载点目录查看。

LVM GC policy

前面了解了如何在k8s中提供LVM支持,umount的时候不删除LVM来为自定义删除策略提供支持,自定义删除策略就需要写一个旁路清理程序,可以是daemon或cron的形式运行,可以基于磁盘容量或pod退出时间进行GC。比较好的方式是不直接清理LVM, 先lvreduce对LVM进行缩容,将未使用的空间还给VG, 这样即提高磁盘使用率,又保留了用户数据,等到合适的时候再删除。注意此处缩容指的是LVM和文件系统两方面,且不能损坏用户的数据为前提。每次GC之后都需要及时上报VG信息,为后面调度提供信息。

schedule pod based on LVM

上面的实现为集群中的每个node提供了一种额外的资源(LVM)的支持, 既然是node级别的资源,就要考虑在调度pod的时候如何选择合适的node assign,需要自定义调度策略,上文中所有对LVM的操作中都提到了要及时上报VG信息,就是为了调度的时候使用这些信息。官方对于node resource提供了调度的支持,参见https://kubernetes.io/docs/tasks/administer-cluster/extended-resource-node/ ,但是这种方式只适合随着pod生命周期结束而结束的资源,例如emptyDir,memroy,cpu等。还有一种扩展是device plugin,可以考虑将LVM作为一种磁盘device使用,这种方式也不适合,因为对于device设备的申请是有粒度的,例如可以说申请一个磁盘设备,但不能说申请1G的空间。

不能通过上述两种声明node resource的方式利用内置的调度策略,我们只能自己实现调度策略了,k8s对于调度的扩展也有很好的支持,可以定义一个scheduler extender提供一个http webhook。要实现一个scheudler extender, 首先要了解kube-scheduler的调度过程,分为三步,首先是做筛选(predict)或称为filter,过滤掉不能调度到其上的node。其次是排序(priorities),为可以调度的node进行打分,决定最适合调度的node;最后是绑定(bind),绑定操作将该pod“分配”给某台node。scheduler-extender相当于上述步骤的“补充协议”, 可选的为上述步骤补充自己的调度逻辑, 当创建一个pod需要调度的时候,首先会执行内置的调度策略,然后将内置调度器的结果传递过来给你的extender server,调度逻辑完成之后将结果返回给kube-scheduler进行下一个过程。

除了kube-scheduler的调度步骤外,kube-scheduler为了提高调度性能有一个“资源占用”的概念: kube-scheduler会在本地有一个cache存放所有的node信息,该cache会与api-server进行同步,调度pod的信息直接从cache中取,当pod调度到某个node上后,会将cache中该node的资源进行“预先占用”,假定资源已经被pod消耗了,其实pod只是调度到了该node上面,还未真正启动起来,未真正占用资源,通过假定调度上去的pod已经占用了该资源,为后面调度的pod提供变化的信息,如果在指定的timeout内,pod还未启动则将预先占用的资源返回给该node,通过这种异步的最终一致性的方案能够有效提高pod的调度效率。此外在高可用的方案中需要配置多个kube-scheduler,因为每个kube-scheduler的cache并不同步,无法多个kube-scheduler同时对外提供服务,此时只能通过选主协议选择其中的一个进行处理请求。

明白了kube-scheduler的实现之后,来仿照kube-scheduler实现我们的scheduler extender, extender的httpserver位置通过kube-scheduler的–policy-config-file或–policy-configmap来配置,前者指定一个config file,后者通过一个configmap来配置,笔者建议用configmap来管理,因为更新配置只需要改变一个地方对于多个kube-scheduler同时生效。并且可以单独定义上述三步骤中的其中某一步。

apiVersion: v1
kind: ConfigMap
metadata:
  name: lvm-scheduler-extender
  namespace: kube-system
data:
 policy.cfg : |
  {
  "kind" : "Policy",
  "apiVersion" : "v1",
  "extenders" : [
    {
          "urlPrefix": "http://localhost:8384/lvm-scheduler",
          "apiVersion": "v1alpha1",
          "filterVerb": "predicates/lvm_resource",
          "bindVerb": "bind",
          "prioritizeVerb": "",
          "weight": 1,
          "enableHttps": false,
          "nodeCacheCapable": false
    }
      ],
  "hardPodAffinitySymmetricWeight" : 10
  }

上面的配置configmap指定了extender webhook的位置,并且定义了filter和bind这两个操作,之所以定义这两个操作是因为我们只关心哪些node可以调度上去,将LVM剩余空间不足以创建pod的node过滤掉,以及最后到底调度到了那台node上以便在scheduler extender的cache中将该node的资源进行占用。需要注意的是系统中只能有一个执行bind操作的binder, 如果extender中指定了binder,kube-scheduler内置的就不会生效了,需要通过k8s client-go来绑定:

clientset.CoreV1().Pods(podNamespace).Bind(&v1.Binding{
        ObjectMeta: metav1.ObjectMeta{Namespace: podNamespace, Name: podName, UID: podUID},
        Target: v1.ObjectReference{
            Kind: "Node",
            Name: nodeName,
        }})

前面在介绍plugin和GC的时候每次操作LVM都需要及时将LVM信息上报来提供extender进行调度决策,那么该向哪里汇报这些VG信息?如何汇报? 这个问题根据不同的场景下有不同的解决方案,首先肯定不能直接向extender上报,因为高可用集群中往往不只有一个exteder示例,所以需要提供一个分离的统一后端存储,所有的extender直接从后端存储里取,可以存储在Mysql或redis中,比较tricky的方式是直接存储在k8s的etcd中,这些数据量比较小不会占用太多空间,也免了额外的操作数据库,但是直接操作etcd有点不妥,可以定义一种CRD资源,为每台node创建一个crd资源实体表示该node可用LVM空间的大小,这样就可以像其他资源一样方便查询,在LVM资源发生变化之后对该crd对象进行patch。在extender中watch该crd资源即可。此外需要提供一个cache进行资源的预先占用,同时提供选主协议的实现,以上都可以参考kube-scheduler中的实现。

summary

麻雀虽小,五脏俱全上述通过实现LVM这种node resource的支持,分别涉及到了storage plugin,scheduelr extender,CRD等,虽然内容较多但是实际编码并不多,感谢kubernetes提供了一种灵活的扩展,感兴趣的可以自己去实现一下。

centos7上测试部署kvm虚拟机

华为的云计算已经摒弃xen架构了,使用kvm。目前kvm已经是一种主流虚拟化架构,所以学习kvm是很有必要的。

一、部署环境

使用vmware workstation部署centos7虚拟机,采用最小化安装,硬盘50G,内存2G,开启cpu虚拟化。网络模式采用桥接,ip地址192.168.3.1,kvm
对虚拟机进行初始化操作,包括关闭selinux 等

sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/sysconfig/selinux
systemctl disable firewalld
systemctl stop firewalld

二、安装kvm

验证cpu是否支持kvm,如果结果中有vmx(Intel)或svm(AMD)字样,就说明CPU的支持的

egrep '(vmx|svm)' /proc/cpuinfo

未分类

2.最小化安装依赖包

yum install epel-release net-tools vim unzip zip wget ftp -y

3.安装kvm及依赖项

yum install qemu-kvm libvirt virt-install bridge-utils -y

4.验证安装结果

lsmod | grep kvm

未分类

5.开启kvm服务

systemctl start libvirtd

systemctl enable libvirtd

6.确认服务运行

systemctl status libvirtd

未分类

7.配置网桥模式
先将 /etc/sysconfig/network-scripts/ 目录下的网卡配置文件备份一份(不要备在当前目录以及子目录下,其他目录随意)

cp ifcfg-ens33 /root/   #这里物理网卡配置名称为ens33,复制到/root/

创建 ifcfg-br0 文件,内容如下

cat >>ifcfg-br0 <<EOF
BOOTPROTO=static
DEVICE=br0
TYPE=Bridge
NM_CONTROLLED=no
IPADDR=192.168.3.50
NETMASK=255.255.255.0
GATEWAY=192.168.3.1
DNS1=202.103.24.68
DNS2=202.103.44.150
EOF

未分类

移除掉原来的 ifcfg-ens33 ,重新创建该文件,内容如下:

BOOTPROTO=none
DEVICE=ens33
NM_CONTROLLED=no
ONBOOT=yes
BRIDGE=br0

未分类

重启网络服务

systemctl restart network

使用ifconfig查看,此时多了块网卡br0

未分类

注意virbr0是kvm内部作为nat使用的,没有配置则自动分配192.168.122.1地址,暂时不用管

三、安装虚拟机

准备操作系统,kvm可以很好的支持linux虚拟机,windows虚拟机需要另外装驱动。创建/home/iso目录,使用xftp上传镜像centos7镜像

未分类

未分类

上传完毕后如下图所示

未分类

2.创建虚拟机存放文件目录

mkdir -p /home/kvm

3.使用virt-install创建虚拟机

virt-install --name centos7_kvm --memory 512 --vcpus=1 --disk /home/kvm/centos7_kvm.img,format=qcow2,size=20 --network bridge=br0 --os-type=linux --os-variant=rhel7.3 --cdrom /home/iso/CentOS-7-x86_64-Minimal-1611.iso --noautoconsole --vnc --vncport=5910 --vnclisten=0.0.0.0

未分类

注意,这里参数最好加上–noautoconsole,不然本tty就会一直被占用,会误以为失败死机
检查虚拟机状态,确认运行

virsh list

未分类

virsh工具的相关选项说明
--name 虚拟机名称
--memory 内存大小
--vcpus= vcpu
--disk 创建硬盘 制定硬盘路径,格式,大小
--network 指定网络
--os-type 指定操作系统类型
--os-variant= 指定操作系统版本
--cdrom 指定光驱安装操作系统
--noautoconsosle 虚拟机创建完毕后不会自动切换tty
--vnc 使用vnc
--vncport vnc端口

4.使用vnc登录虚拟机安装操作系统

未分类

安装操作系统

未分类

因为连接br0,虚拟机可以使用dhcp获取ip地址

未分类

kvm中虚拟机创建成功,可以直接使用ssh连接kvm虚拟机进行配置

解决ubuntu安装kubernetes时的网络问题

在kubernetes安装过程中,由于众所周知的原因,导致很多安装包等无法下载。本文记录了解决此问题的步骤。

1、安装shadowsocks

apt install shadowsocks -y

2、将shadowsocks配置写入配置文件

root@ubuntu:~# cat /etc/shadowsocks.json 
{
"server":"********",
"server_port":8086,
"local_address": "127.0.0.1",
"local_port":1080,
"password":"******",
"timeout":300,
"method":"aes-256-cfb",
"fast_open": false,
"workers": 1
}

3、安装privoxy,并编辑其配置文件

root@ubuntu:~# apt-get install privoxy

在/etc/privoxy/config文件末尾加上如下内容:

listen-address 127.0.0.1:9909
forward-socks5 / 127.0.0.1:1080 .

注意最后一行的点.

4、在一个session中启动shadowsocks,启动命令为

sslocal -c /etc/shadowsocks.json

在另一个session中,启动privoxy

systemctl start privoxy

5、这时候,如果哪个session需要下载kubernetes软件等,在当前session执行如下命令,加入环境变量

root@host1:~# export https_proxy="http://127.0.0.1:9909"
root@host1:~# export http_proxy="http://127.0.0.1:9909"

kubernetes pod的弹性伸缩

概念

HPA是kubernetes里面pod弹性伸缩的实现,它能根据设置的监控阀值进行pod的弹性扩缩容,目前默认HPA只能支持cpu和内存的阀值检测扩缩容,但也可以通过custom metric api 调用prometheus实现自定义metric 来更加灵活的监控指标实现弹性伸缩。但hpa不能用于伸缩一些无法进行缩放的控制器如DaemonSet。这里我们用的是resource metric api.

未分类

实现hpa的两大关键

1、监控指标的获取
早期kubernetes版本是使用hepster,在1.10后面版本更推荐使用metric-server

hepster简单来说是api-server获取节点信息,然后通过kubelet获取监控信息,因为kubelet内置了cadvisor。

metric-server,简单来说是通过metric-api来获取节点信息和监控信息。https://github.com/kubernetes-incubator/metrics-server

2、伸缩判定算法
HPA通过定期(定期轮询的时间通过–horizontal-pod-autoscaler-sync-period选项来设置,默认的时间为30秒)查询pod的状态,获得pod的监控数据。然后,通过现有pod的使用率的平均值跟目标使用率进行比较。
pod的使用率的平均值:
监控资源1分钟使用的平均值/设定的每个Pod的request资源值

扩容的pod数计算公式

TargetNumOfPods = ceil(sum(CurrentPodsCPUUtilization) / Target)

celi函数作用:
返回大于或者等于指定表达式的最小整数

在每次扩容和缩容时都有一个窗口时间,在执行伸缩操作后,在这个窗口时间内,不会在进行伸缩操作,可以理解为类似等一下放技能的冷却时间。默认扩容为3分钟(–horizontal-pod-autoscaler-upscale-delay),缩容为5分钟(–horizontal-pod-autoscaler-downscale-delay)。另外还需要以下情况下才会进行任何缩放avg(CurrentPodsConsumption)/ Target下降9%,进行缩容,增加至10%进行扩容。以上两条件需要都满足。

这样做好处是:
1、判断的精度高,不会频繁的扩缩pod,造成集群压力大。
2、避免频繁的扩缩pod,防止应用访问不稳定。

未分类

实现hpa的条件:
1、hpa不能autoscale daemonset类型control
2、要实现autoscale,pod必须设置request

配置HPA

这里以kubeadm 部署和的kubernetes 1.11和Rancher2.0部署的kubernetes 1.10为例
环境信息

操作系统:ubuntu16.04
kubernetes版本:1.11
rancher:2.0.6

kubeadm方式

将metric-server从github拉取下来

git clone [email protected]:kubernetes-incubator/metrics-server.git

早期kubelet的10255端口是开放,但后面由于10255是一个非安全的端口容易被入侵,所以被关闭了。metric-server默认是从kubelet的10255端口去拉取监控信息的,所以这里需要修改从10250去拉取

edit  metrics-server/deploy/1.8+/metrics-server-deployment.yaml

修改source为以下内容。

–source=kubernetes.summary_api:https://kubernetes.default?kubeletHttps=true&kubeletPort=10250&insecure=true

apply yaml文件

kubectl apply -f metrics-server/deploy/1.8+/.1
![](http://ohx02qrb8.bkt.clouddn.com/kube_hpa_3.png)
![](http://ohx02qrb8.bkt.clouddn.com/kube_hpa_4.png)
![](http://ohx02qrb8.bkt.clouddn.com/kube_hpa_5.png)
等待一分钟  
执行
kubect top node
kubectl top pods

查看pod和node监控信息

未分类

创建个一个deployment,配置hpa测试

apiVersion: v1
kind: Service
metadata:
  name: podinfo
  labels:
    app: podinfo
spec:
  type: NodePort
  ports:
    - port: 9898
      targetPort: 9898
      nodePort: 31198
      protocol: TCP
  selector:
    app: podinfo
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: podinfo
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: podinfo
      annotations:
        prometheus.io/scrape: 'true'
    spec:
      containers:
      - name: podinfod
        image: stefanprodan/podinfo:0.0.1
        imagePullPolicy: Always
        command:
          - ./podinfo
          - -port=9898
          - -logtostderr=true
          - -v=2
        volumeMounts:
          - name: metadata
            mountPath: /etc/podinfod/metadata
            readOnly: true
        ports:
        - containerPort: 9898
          protocol: TCP
        resources:
          requests:
            memory: "32Mi"
            cpu: "1m"
          limits:
            memory: "256Mi"
            cpu: "100m"
      volumes:
        - name: metadata
          downwardAPI:
            items:
              - path: "labels"
                fieldRef:
                  fieldPath: metadata.labels
              - path: "annotations"
                fieldRef:
                  fieldPath: metadata.annotations

apply yaml文件

配置hpa

apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  name: podinfo
spec:
  scaleTargetRef:
    apiVersion: extensions/v1beta1
    kind: Deployment
    name: podinfo
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      targetAverageUtilization: 80
  - type: Resource
    resource:
      name: memory
      targetAverageValue: 200Mi

apply yaml文件

get hpa

未分类

测试
使用webbench进行压力测试。

wget http://home.tiscali.cz/~cz210552/distfiles/webbench-1.5.tar.gz
tar -xvf webbench-1.5.tar.gz
cd webbench-1.5/
make && make install

webbench -c 1000 -t 12360 http://172.31.164.104:31198/

未分类

可以看见随着cpu压力的增加,已经自动scale了,需要注意的是,scale up是一个阶段性的过程,并不是一次性就直接scale到max了,而是一个阶段性的过程,判定算法就是上文介绍的内容。
隔断时间没操作压力下来后,自动缩减pod

未分类

Rancher2.0

使用rancher2.0部署的kubernetes如何开启HPA,因为rancher2.0将所有的kubernetes组件都容器化了,所以有些地方需要配置
配置方法
rancher2.0部署的kubernetes默认没有配置Metrics API aggregator的证书所以需要手动生成
生成证书文件

cat >> /etc/kubernetes/ssl/ca-config.json<< EOF
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "kubernetes": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ],
        "expiry": "87600h"
      }
    }
  }
}
EOF
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
mv cfssljson_linux-amd64  /usr/bin/cfssljson
mv cfssl_linux-amd64  /usr/bin/cfssl
chmod a+x  /usr/bin/cfssljson
chmod a+x  /usr/bin/cfssl
cd /etc/kubernetes/ssl/
cat >> front-proxy-ca-csr.json <<EOF
{
    "CN": "kubernetes",
    "key": {
        "algo": "rsa",
        "size": 2048
    }
}
EOF
cat >>front-proxy-client-csr.json<<EOF
{
    "CN": "front-proxy-client",
        "algo": "rsa",
        "size": 2048
    }
}
EOF
cfssl gencert   -initca front-proxy-ca-csr.json |
cfssljson -bare front-proxy-ca
cfssl gencert   -ca=front-proxy-ca.pem  
  -ca-key=front-proxy-ca-key.pem 
-config=/etc/kubernetes/ssl/ca-config.json   
-profile=kubernetes   
front-proxy-client-csr.json | cfssljson -bare front-proxy-client

拷贝证书导集群其他节点

scp /etc/kubernetes/ssl/front-*

修改api-server的启动参数

--requestheader-client-ca-file=/etc/kubernetes/ssl/front-proxy-ca.pem 
--requestheader-allowed-names=front-proxy-client
--proxy-client-cert-file=/etc/kubernetes/ssl/front-proxy-client.pem
--proxy-client-key-file=/etc/kubernetes/ssl/front-proxy-client-key.pem

rancher2.0 custom集群时需要rke的启动修改参数,来修改api-server启动参数

未分类

view in API—>edit

未分类

将其部署方式的value设置为null

未分类

未分类

未分类

修改rancherKubernetesEngineConfig
这里面内容是json的,可以复制出来通过json解析工具解析

未分类

未分类

我们需要添加的参数
api-server配置

--requestheader-client-ca-file=/etc/kubernetes/ssl/front-proxy-ca.pem 
--requestheader-allowed-names=front-proxy-client
--proxy-client-cert-file=/etc/kubernetes/ssl/front-proxy-client.pem
--proxy-client-key-file=/etc/kubernetes/ssl/front-proxy-client-key.pem

json文件

{"addonJobTimeout":30,"authentication":{"strategy":"x509","type":"/v3/schemas/authnConfig"},"authorization":{"type":"/v3/schemas/authzConfig"},"bastionHost":{"sshAgentAuth":false,"type":"/v3/schemas/bastionHost"},"cloudProvider":{"type":"/v3/schemas/cloudProvider"},"ignoreDockerVersion":true,"ingress":{"provider":"nginx","type":"/v3/schemas/ingressConfig"},"kubernetesVersion":"v1.10.1-rancher1","network":{"canalNetworkProvider":{"iface":"","type":"/v3/schemas/canalNetworkProvider"},"plugin":"canal","type":"/v3/schemas/networkConfig"},"services":{"etcd":{"extraArgs":{"election-timeout":"5000","heartbeat-interval":"500"},"snapshot":false,"type":"/v3/schemas/etcdService"},"kubeApi":{"extraArgs":{"enable-aggregator-routing":"true","proxy-client-cert-file":"/etc/kubernetes/ssl/front-proxy-client.pem","proxy-client-key-file":"/etc/kubernetes/ssl/front-proxy-client-key.pem","requestheader-allowed-names":"front-proxy-client","requestheader-client-ca-file":"/etc/kubernetes/ssl/front-proxy-ca.pem","requestheader-extra-headers-prefix":"X-Remote-Extra-","requestheader-group-headers":"X-Remote-Group","requestheader-username-headers":"X-Remote-User"},"podSecurityPolicy":false,"type":"/v3/schemas/kubeAPIService"},"kubeController":{"type":"/v3/schemas/kubeControllerService"},"kubelet":{"extraArgs":{"anonymous-auth":"true","read-only-port":"10255"},"failSwapOn":false,"type":"/v3/schemas/kubeletService"},"kubeproxy":{"type":"/v3/schemas/kubeproxyService"},"scheduler":{"type":"/v3/schemas/schedulerService"},"type":"/v3/schemas/rkeConfigServices"},"sshAgentAuth":false,"type":"/v3/schemas/rancherKubernetesEngineConfig"}

未分类

然后集群会出现update状态,会将api-server和kubelt滚动更新

未分类

部署metric-server
修改yaml文件

apiVersion: v1
kind: ServiceAccount
metadata:
  name: metrics-server
  namespace: kube-system
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: metrics-server
  namespace: kube-system
  labels:
    k8s-app: metrics-server
spec:
  selector:
    matchLabels:
      k8s-app: metrics-server
  template:
    metadata:
      name: metrics-server
      labels:
        k8s-app: metrics-server
    spec:
      serviceAccountName: metrics-server
      containers:
      - name: metrics-server
        image: wanshaoyuan/metric-server:v1.0
        imagePullPolicy: Always
        command:
        - /metrics-server
        - --source=kubernetes.summary_api:https://kubernetes.default?kubeletHttps=true&kubeletPort=10250&insecure=true

部署

kubectl apply -f /root/k8s-prom-hpa/metrics-server/.

未分类

创建应用,查看hpa

kubectl apply -f /root/k8s-prom-hpa/podinfo/.

查看hpa

未分类

过几分钟可以看见应用在弹性扩容

未分类

https://zhuanlan.zhihu.com/p/34555654
https://github.com/kubernetes/community/blob/master/contributors/design-proposals/autoscaling/horizontal-pod-autoscaler.md#autoscaling-algorithm
https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#support-for-metrics-APIs

Kubernetes之配置与自定义DNS服务

本文解释如何为kubernetes集群配置及自定义DNS服务。从kubernetes1.11版本开始,coreDNS插件被包含在GA发行版中,并且被kubeadm默认安装。详情:Configuring CoreDNS and Using CoreDNS for Service Discovery。除特别说明,本文讨论的是默认dns插件。

介绍

Kubernetes的DNS功能以插件形式提供,是自动启动的系统内置服务。服务包含如下三个容器:

  • kubedns:监控Kubernetes master的service与endpoint变更,增删改DNS记录,将相关数据保存在内存中,为DNS查询提供服务。
  • dnsmasq: 充当DNS缓存,提高性能。
  • sidecar:挂斗容器,对dnsmasq与kubedns进行单点健康检查。

DNS服务拥有静态IP地址,将各节点kubeletr的–cluster-dns=设置成DNS服务的静态IP地址,当kubelet创建容器时则将此地址传递给容器。Kubernetes的DNS服务基于skyDNS库,支持forward lookups (A records)、service lookups (SRV records)、reverse IP address lookups (PTR records)。

从节点继承DNS配置

当kubelet启动容器时,除使用kubernetes内置的DNS服务,默认从节点继承其DNS配置。此特性使kubernetes系统中的容器DNS行为高度依赖低层节点,建议关闭,设置kubelet–resolv-conf选项为用户自定义配置文件,而非系统默认/etc/resolve.conf,这样容器继承的DNS配置由用户提供的配置文件决定,而非节点,降低耦合度。

配置存根域及上游DNS服务器

集群管理员可通过为kubernetes中DNS服务kube-system:kube-dns提供ConfigMap对象,设置自定义存根域及上游DNS服务器。以下示例为DNS服务配置一个存根域及两个上游DNS服务器:

apiVersion: v1
kind: ConfigMap
metadata:
  name: kube-dns
  namespace: kube-system
data:
  stubDomains: |
    {"acme.local": ["1.2.3.4"]}
  upstreamNameservers: |
    ["8.8.8.8", "8.8.4.4"]

如果查询请求的前缀为”acme.local”则被直接转发到1.2.3.4。下表列出不同域名前缀与DNS服务器对应关系:

未分类

对pod的影响

如果pod Spec之dnsPolicy设置为”Default”或者”Node”,则用户自定义存根服务器与上游服务器对pod没有影响。当值为”Default”时,pod之DNS配置完全从节点继承。如果为Node,则取决于pod Spec中的dnsConfig配置。

当dnsPolicy设置为”ClusterFirst”时,pod的DNS配置分成没无自定义存根域与上游服务器、有自定义存根域与上游服务器两种情况。

无自定义存根域与上游服务器:如果查询请求之域名前缀与集群默认域名匹配,则使用kubernetes内置DNS服务,如果不匹配则使用从节点继承之DNS服务。

有自定义存根域与上游服务器,域名解析流程如下:

  1. 请求首先发送到kube-dns缓存层。

  2. 在缓存层,检查请求的域名前缀并将请求转发到与之匹配的DNS服务器,流程如下:

  • 与集群域名前缀匹配,如“.cluster.local”,则发往kube-dns。

  • 如与存根域匹配,如“.acme.local”, 则发往匹配的存根域服务器。

  • 否则,发往上游服务器。

未分类

ConfigMap选项

未分类

配置CoreDNS

从1.9版本开始,CoreDNS成为GA可选特性,将来可能会取代kube-dns成为默认集群默认DNS解决方案,CoreDNS具备kube-dns所有功能并更强大。在CoreDNS插件内部通过一种Corefile文件管理配置。可以直接将为kube-dns设置的ConfigMap直接指定给CoreDNS,CoreDNS自动将此ConfigMap转换成Corefile。示例如下:

apiVersion: v1
data:
  federations: |
    {"foo" : "foo.feddomain.com"}
  stubDomains: |
    {"abc.com" : ["1.2.3.4"], "my.cluster.local" : ["2.3.4.5"]}
  upstreamNameservers: |
    ["8.8.8.8", "8.8.4.4"]
kind: ConfigMap

转换结果:

.:53 {
        errors
        health
        kubernetes cluster.local  in-addr.arpa ip6.arpa {
           upstream  8.8.8.8 8.8.4.4
           pods insecure
           fallthrough in-addr.arpa ip6.arpa
        }
        federation cluster.local {
           foo foo.feddomain.com
        }
        prometheus :9153
        proxy .  8.8.8.8 8.8.4.4
        cache 30
    }
    abc.com:53 {
        errors
        cache 30
        proxy . 1.2.3.4
    }
    my.cluster.local:53 {
        errors
        cache 30
        proxy . 2.3.4.5
    }

使用 kubeadm 安装k8s

安装版本

Kubernetes – 1.11.1

机器规划

未分类

注:三台机器已做key认证并添加hosts, 方便传送文件

系统配置(三台机器都执行)

关闭selinux及firewalld

sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
setenforce 0
systemctl stop firewalld && systemctl disable firewalld

内核参数调整

cat <<EOF >  /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system

关闭swap, 注释fstab中的swap配置

swapoff -a

注: k8s 版本1.8开始要求关闭系统的swap,否则启动不了kubelet;

安装docker并启动(三台机器都执行)

docker从1.13版本之后采用时间线的方式作为版本号,分为社区版CE和企业版EE; 比如: 18.06 为18年6月份发布的版本;

安装包官方地址:

https://download.docker.com/linux/centos/7/x86_64/stable/Packages/

下载安装 docker-ce 17.03版本:

wget -c https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-17.03.2.ce-1.el7.centos.x86_64.rpm
wget -c https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-selinux-17.03.2.ce-1.el7.centos.noarch.rpm
yum install -y docker-ce-selinux-17.03.2.ce-1.el7.centos.noarch.rpm docker-ce-17.03.2.ce-1.el7.centos.x86_64.rpm

注:本次安装的版本为 17.03 ; k8s-1.11.1 对应的最高版本docker是 17.03 ;

修改docker启动配置文件:

/usr/lib/systemd/system/docker.service

# 指定监听端口、数据存储目录以及加速镜像源
ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H 127.0.0.1:8888 -g /data/docker --registry-mirror=http://xxxx.io --exec-opt native.cgroupdriver=systemd

启动 docker :

systemctl daemon-reload && systemctl enable docker && systemctl start docker

导入必要的镜像

默认使用 kubeadm 初始化集群时需要从 k8s.gcr.io 地址上拉取相关镜像,如果可以科学上网的,这一步可以省略;

master节点执行:

images=(kube-apiserver-amd64.tar kube-controller-manager-amd64.tar kube-scheduler-amd64.tar kubernetes-dashboard-amd64.tar etcd-amd64.tar coredns.tar flannel.tar kube-proxy-amd64.tar pause.tar)
for i in ${images[@]};do
    docker load < $(dirname $script_dir)/$i
done

node节点执行:

images=(flannel.tar kube-proxy-amd64.tar pause.tar)
for i in ${images[@]};do
    docker load < $(dirname $script_dir)/$i
done

镜像分享地址:

链接: https://pan.baidu.com/s/1jtT0qHpcz1WjovIBP6JOwQ 密码:5xxn

安装 kubeadm (三台机器都执行)

添加 yum 源:

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 
EOF

安装 kubeadm :

# 列出最新版本
yum list kubeadm --showduplicates
# 安装
yum install kubeadm-1.11.1

注:安装 kubeadm ,相关依赖会安装 kubectl、kubelet、kubernetes-cni ; kubectl 是管理集群的工具,kubelet 是每个node节点都会运行的一个服务,用于管理节点的docker启动、网络组件等功能;

配置启动 kubelet (三台机器都执行)

确保kubelet和docker使用同一个cgroupdriver, 这里使用systemd;

kubelet 额外参数配置:

/etc/sysconfig/kubelet

KUBELET_EXTRA_ARGS="--runtime-cgroups=/systemd/system.slice --kubelet-cgroups=/systemd/system.slice"

启动 kubelet :

systemctl enable kubelet && systemctl start kubelet

初始化k8s集群 (master机器执行)

初始化:

kubeadm init --apiserver-advertise-address 10.211.55.10 --pod-network-cidr=10.10.0.0/16  --kubernetes-version=v1.11.1

初始化完成后会有以下提示:

[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy

Your Kubernetes master has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

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

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

You can now join any number of machines by running the following on each node
as root:

  kubeadm join 10.211.55.10:6443 --token 4zfhdz.8jue59q95hzoc7p9 --discovery-token-ca-cert-hash sha256:da756adb30db06963db480d3868b9acd02c2e38271314baf62e9d28c6629ae92

增加kubectl权限访问:

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

配置 k8s 网络 – flannel

Kubernetes支持Flannel、Calico、Weave network等多种cni网络Drivers;

配置 flannel :

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

如果有多张网卡,需要在kube-flannel.yml中使用–iface参数指定集群主机内网网卡的名称, 类似 :

args:
- --ip-masq
- --kube-subnet-mgr
- --iface=eth1

查看 k8s 集群状态

查看集群状态 :

kubectl get cs

查看 pods :

kubectl get pod --all-namespaces

其它节点添加到集群

集群初始化完成后可以看到,最后有提示加入集群的命令,但token是有时间限制的,可能过一段时间就过期了,可以通过以下命令成生新的命令:

kubeadm token create --print-join-command

输出类似:

kubeadm join 10.211.55.10:6443 --token pxlvg5.puu7a0mrhpoif16e --discovery-token-ca-cert-hash sha256:f732ceef958151c56583641048ce6a11c39f960166969fb8f782374c3b4a7570

查看已有 token :

kubeadm token list

部署 k8s Dashboard

下载部署配置文件:

wget https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml

指向端口类型为 NodePort , 可以使用 节点ip:端口 访问 :

修改 kubernetes-dashboard.yaml

# ------------------- Dashboard Service ------------------- #

kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kube-system
spec:
  type: NodePort
  ports:
    - port: 443
      targetPort: 8443
  selector:
    k8s-app: kubernetes-dashboard

因 k8s 在1.6版本以后 kube-apiserver 启用了 RBAC 授权, 因此需要认证权限配置文件 :

增加 kubernetes-dashboard-admin.rbac.yaml

---
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard-admin
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: kubernetes-dashboard-admin
  labels:
    k8s-app: kubernetes-dashboard
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: kubernetes-dashboard-admin
  namespace: kube-system

节点增加标签用法:

kubectl label nodes <node-name> <label-key>=<label-value>
kubectl get nodes
kubectl label nodes k8s-master1 k8s-app=kubernetes-dashboard

查看 dashboard 分配到的 NodePort :

kubectl get svc,pod --all-namespaces | grep dashboard

创建 dashboard 的 pod :

kubectl create -f kubernetes-dashboard.yaml
kubectl create -f kubernetes-dashboard-admin.rbac.yaml

查看登陆 dashboard 的token :

kubectl -n kube-system describe $(kubectl -n kube-system get secret -n kube-system -o name | grep namespace) | grep token

kubectl 命令补全

yum install -y bash-completion
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc

K8S之traefik

Traefik

Traefik是一个用Golang开发的轻量级的Http反向代理和负载均衡器。由于可以自动配置和刷新backend节点,目前可以被绝大部分容器平台支持,例如Kubernetes,Swarm,Rancher等。由于traefik会实时与Kubernetes API交互,所以对于Service的节点变化,traefik的反应会更加迅速。总体来说traefik可以在Kubernetes中完美的运行.

Traefik 还有很多特性如下:

  • 速度快
  • 不需要安装其他依赖,使用 GO 语言编译可执行文件
  • 支持最小化官方 Docker 镜像
  • 支持多种后台,如 Docker, Swarm mode, Kubernetes, Marathon, Consul, Etcd, Rancher, Amazon ECS 等等
  • 支持 REST API
  • 配置文件热重载,不需要重启进程
  • 支持自动熔断功能
  • 支持轮训、负载均衡
  • 提供简洁的 UI 界面
  • 支持 Websocket, HTTP/2, GRPC
  • 自动更新 HTTPS 证书
  • 支持高可用集群模式

接下来我们使用 Traefik 来替代 Nginx + Ingress Controller 来实现反向代
理和服务暴漏。

那么二者有什么区别呢?简单点说吧,在 Kubernetes 中使用 nginx 作为前端负载均衡,通过 Ingress Controller 不断的跟 Kubernetes API 交互,实时获取后端 Service、Pod 等的变化,然后动态更新 Nginx 配置,并刷新使配置生效,来达到服务自动发现的目的,而 Traefik 本身设计的就能够实时跟 Kubernetes API 交互,感知后端 Service、Pod 等的变化,自动更新配置并热重载。大体上差不多,但是 Traefik 更快速更方便,同时支持更多的特性,使反向代理、负载均衡更直接更高效。

1.Role Based Access Control configuration (Kubernetes 1.6+ only)

kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik-rbac.yaml

授权,官方文档不懂下下来看文档

2.Deploy Træfik using a Deployment or DaemonSet

To deploy Træfik to your cluster start by submitting one of the YAML files to the cluster with kubectl:

kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik-deployment.yaml   此模板有些问题,我先用ds模板

kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik-ds.yaml

deployment和ds的区别:ds会在每台node上都创造一个pod.而deploy是人为控制的副本。如果几台很多了,没有必要用ds,比如100台 会造100个pod,没有意义。自己用ds模板改下,kind: Deployment

如下

直接找到DS模板吧kind改成deploy模式
kind: Deployment

3.Check the Pods

# kubectl --namespace=kube-system get pods -o wide 
traefik-ingress-controller-79877bbc66-p29jh 1/1 Running 0 32m   10.249.243.182    k8snode2-175v136​

查找一下在那台服务器上,deploy会随机分配一台服务器

4.Ingress and UI

kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/ui.yaml.

自己再造个web测试用

apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  template:
    metadata:
      labels:
        name: nginx-svc
        namespace: default
spec:
  selector:
    run: ngx-pod
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: ngx-pod
spec:
  replicas: 4
  template:
    metadata:
      labels:
        run: ngx-pod
    spec:
      containers:
      - name: nginx
        image: nginx:1.10
        ports:
        - containerPort: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ngx-ing
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
  - host: www.ha.com
    http:
      paths:
      - backend:
          serviceName: nginx-svc
          servicePort: 80

5.测试成功

未分类

6.HTTPS证书

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: traefik-web-ui
  namespace: kube-system
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
  - host: traefik-ui.minikube
    http:
      paths:
      - backend:
          serviceName: traefik-web-ui
          servicePort: 80
  tls:
   - secretName: traefik-ui-tls-cert

官方是怎么导入证书的呢? 注:key和crt必须要有

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=traefik-ui.minikube"
kubectl -n kube-system create secret tls traefik-ui-tls-cert --key=tls.key --cert=tls.crt

7.Basic Authentication

A. Use htpasswd to create a file containing the username and the MD5-encoded password:
htpasswd -c ./auth myusername
You will be prompted for a password which you will have to enter twice. htpasswd will create a file with the following:
cat auth
myusername:$apr1$78Jyn/1K$ERHKVRPPlzAX8eBtLuvRZ0
B. Now use kubectl to create a secret in the monitoring namespace using the file created by htpasswd
kubectl create secret generic mysecret --from-file auth --namespace=monitoring
Note
Secret must be in same namespace as the Ingress object.
C. Attach the following annotations to the Ingress object:
    ingress.kubernetes.io/auth-type: "basic"
    ingress.kubernetes.io/auth-secret: "mysecret"
They specify basic authentication and reference the Secret mysecret containing the credentials.
Following is a full Ingress example based on Prometheus:
#配置文件如下
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
 name: prometheus-dashboard
 namespace: monitoring
 annotations:
   kubernetes.io/ingress.class: traefik
   ingress.kubernetes.io/auth-type: "basic"
   ingress.kubernetes.io/auth-secret: "mysecret"
spec:
 rules:
 - host: dashboard.prometheus.example.com
   http:
     paths:
     - backend:
         serviceName: prometheus
         servicePort: 9090

模板1 多域名暴漏端口:再看一下 UI 页面,立马更新过来,可以看到刚刚配置的 dashboard.k8s.traefik 和 ela.k8s.traefik

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: dashboard-ela-k8s-traefik
  namespace: kube-system
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
  - host: dashboard.k8s.traefik
    http:
      paths:
      - path: /  
        backend:
          serviceName: kubernetes-dashboard
          servicePort: 80
  - host: ela.k8s.traefik
    http:
      paths:
      - path: /  
        backend:
          serviceName: elasticsearch-logging
          servicePort: 9200

模板2

注意:这里我们根据路径来转发,需要指明 rule 为 PathPrefixStrip,配置为 traefik.frontend.rule.type: PathPrefixStrip

再看一下 UI 页面,也是立马更新过来,可以看到刚刚配置的 my.k8s.traefik/dashboard 和 my.k8s.traefik/kibana

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-k8s-traefik
  namespace: kube-system
  annotations:
    kubernetes.io/ingress.class: traefik
    traefik.frontend.rule.type: PathPrefixStrip
spec:
  rules:
  - host: my.k8s.traefik
    http:
      paths:
      - path: /dashboard
        backend:
          serviceName: kubernetes-dashboard
          servicePort: 80
      - path: /kibana
        backend:
          serviceName: kibana-logging
          servicePort: 5601

8.自动熔断

在集群中,当某一个服务大量出现请求错误,或者请求响应时间过久,或者返回500+错误状态码时,我们希望可以主动剔除该服务,也就是不在将请求转发到该服务上,而这一个过程是自动完成,不需要人工执行。Traefik 通过配置很容易就能帮我们实现,Traefik 可以通过定义策略来主动熔断服务。

  • NetworkErrorRatio() > 0.5:监测服务错误率达到50%时,熔断。
  • LatencyAtQuantileMS(50.0) > 50:监测延时大于50ms时,熔断。
  • ResponseCodeRatio(500, 600, 0, 600) > 0.5:监测返回状态码为[500-600]在[0-600]区间占比超过50%时,熔断。

案例

apiVersion: v1
kind: Service
metadata:
  name: wensleydale
  annotations:
    traefik.backend.circuitbreaker: "NetworkErrorRatio() > 0.5" 

9.官方文档:

其他多看官方文档

https://docs.traefik.io/user-guide/kubernetes/

10.update

由于业务需求,node会扩充, ds模式多了会浪费资源 20台node+,我们怎么把traefik固定在几台机器上。查了一些文档找到了这个解决方法。

给node打标签,用ds模式启动标签化节点 :https://www.kubernetes.org.cn/daemonset 参考文档。

案例:

给三台node打标签

kubectl label nodes k8snode1-174v136-taiji traefik=svc
kubectl label nodes k8snode2-175v136-taiji traefik=svc
kubectl label nodes k8snode3-176v136-taiji traefik=svc​
查看标签
[root@k8s-m1 Traefik]# kubectl get nodes --show-labels
NAME                     STATUS    ROLES     AGE       VERSION   LABELS
k8snode1-174v136-taiji   Ready     node      42d       v1.10.4   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=k8snode1-174v136-taiji,node-role.kubernetes.io/node=,traefik=svc
[root@k8s-m1 Traefik]# cat traefik-ds.yaml 
kind: DaemonSet
apiVersion: extensions/v1beta1
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
  labels:
    k8s-app: traefik-ingress-lb
spec:
  template:
    metadata:
      labels:
        k8s-app: traefik-ingress-lb
        name: traefik-ingress-lb
    spec:
      nodeSelector:
        traefik: "svc"            #重点2行
...................
验证
[root@k8s-m1 Traefik]# kubectl get ds -n kube-system 
NAME                         DESIRED   CURRENT   READY     UP-TO-DATE   AVAILABLE   NODE SELECTOR  
traefik-ingress-controller   3         3         3         3            3           traefik=svc

总结:后期可以根据业务量加标签扩展traefik节点