更多官方文档

https://kubernetes.io/zh/docs/tasks/administer-cluster/network-policy-provider/calico-network-policy/
https://www.kubernetes.org.cn/cronjob

使用kubeadm 部署k8s集群

ps: k8s 不能直接管理容器 最小单位为pod 需要借助docker

前期准备
1. 三台虚拟机 分别设置主机名 hostnamectl set-hostname master1 、worker1 、worker2
2. 网络修改 vi /etc/sysconfig/network-scripts/ifcfg-ens33
  BOOTPROTO  none/static  
  IPADDR="192.168.199.128" 当前虚拟机ip
  PREFIX="24"  
  GATWAY="192.168.199.2"  一般为当前网段的.2
  DNS1="119.29.29.29"
  重启网卡  systemctl restart network  
3. 安全配置关闭firewalld selinux
  systemctl stop  firewalld  
  systemctl disable  firewalld   
  sed -ri 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config 
4. 时间同步
 yum -y install ntpdate  
 ntpdate time1.aliyun.com
6. kubeadm安装需要关闭swap 分区
  vim /etc/fstab  free -m 查看 如果有swap分区 需要关闭
7. 添加网桥过滤
   cat /etc/sysctl.d/k8s.cof  
   net.bridge.bridge-nf-call-ip6tables =1 
   net.bridge.bridge-nf-call-iptables =1 
   net.ipv4.ip_forward = 1  
   vm.swappiness = 0   
   modprobe br_netfilter  
   sysctl -p /etc/sysctl.d/k8s.conf  
8. 安装 ipvs
   yum -y install ipset ipvsadm
  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  

 权限改为 755   
 chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod |grep -e ip_vs -e nf_conntrack_ipv4 
9. 安装docker
  wget -O /etc/yum.repos.d/docker-ce.repo  https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo  
  yum -y install --setopt=obsoletes=0  docker-ce-18.06.3.ce-3.el7   
  使用18.06 高版本配置可能需要修改  
  systemctl enable  docker && systemctl start  docker
10. 修改资源配置
vim  /etc/docker/daemon.json   
{
 "exec-opts":["native.cgroupdriver=systemd"],
"registry-mirrors":["https://docker.mirrors.ustc.edu.cn"]
}
11. 集群软件安装
yum -y install --setopt=obsoletes=0 kubeadm-1.17.2-0 kubelet-1.17.2-0 kubectl-1.17.2-0
kubeadm  初始化集群  
kubelet 接受api-server 指令 管理pod  
kubectl  集群命令管理工具    
12. 修改配置
  cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
       http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
保持cgroupdriver  docker与kubelet 一致 
vim /etc/sysconfig/kublet  
KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"
systemctl enable kubelet 
  • 这里是我设置的代理 k8s 的镜像需要翻墙才能pull
mkdir -p /etc/systemd/system/docker.service.d &&
cat > /etc/systemd/system/docker.service.d/https-proxy.conf << EOF
[Service]
Environment="HTTP_PROXY=192.168.1.5:9999/" "HTTPS_PROXY=192.168.1.5:9999/" "NO_PROXY=localhost,127.0.0.1,docker-registry.example.com,"
EOF 
systemctl daemon-reload
systemctl restart docker
systemctl show --property=Environment docker  
13. 保存镜像传输到其他服务器
worker 服务器只需要这两个镜像  
docker save -o kube-proxy.tar k8s.gcr.io/kube-proxy    
docker save -o pause .......
14. k8s 集群初始化
在master 节点 
kubeadm init --kubernetes-version=v1.17.3 --pod-network-cidr=172.16.0.0/16 --apiserver-advertise-address=主机ip192.168.137.132
docker pull rancher/calico-cni:v3.8.1;
docker pull rancher/calico-node:v3.8.1;
docker pull calico/kube-controllers:v3.13.0-0-g15e951d;  
docker pull calico/pod2daemon-flexvol:release-v3.13;

下载 calico.yaml到~目录 我是在官网下载做了下面的修改  

9             - name: CLUSTER_TYPE
620               value: "k8s,bgp"
621             # Auto-detect the BGP IP address.
622             - name: IP
623               value: "autodetect"
624             - name: IP_AUTODETECTION_METHOD
625               value: "interface=ens.*"


             - name: CALICO_IPV4POOL_CIDR
639               value: "172.16.0.0/16"

15. 初始化之后需要做什么 在初始化结束会有提示
Your Kubernetes control-plane has initialized successfully!

创建文件夹 
  mkdir -p $HOME/.kube 
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config
Then you can join any number of worker nodes by running the following on each as root:
在worker节点中执行下面内容 加入集群
kubeadm join 192.168.137.132:6443 --token hbb5ve.v0ho11tpni2gjw4i \
    --discovery-token-ca-cert-hash sha256:028e5215303b520ec0fa1d32e1812d238f148eb95440489dd48ffe4d4a6000f0 
  • 查看集群节点状态 kebectl get nodes
  • 查看集群健康状态 kubecel get cs 或者 kubectl cluster-info
  • 工作状态 kubectl get pods --namespace kube-system

集群工具 kubectl

 有 .kube/config 才可以使用kubectl  
 可以将这个文件复制到 worker机器 

Namespace 命名空间

  • 介绍
    多用户 实现资源隔离

属于逻辑隔离
属于管理边界
不属于网络边界(不需要部署多套网络构建)
可以针对每个 namespace做资源配额

  • 查看 NameSpace
    kubectl get namespace
    default 默认
    kube-node-lease 集群节点租约状态
    kube-public 所有用户都可访问 包括未认证用户
    kube-system kubernetes集群在使用
  • 创建NameSpace
    命令创建

kubectl create namespace test
yml资源清单创建
kubectl apply -f create-ns.yml

apiVersion: v1 
kind: Namespace 
metadata:
  name: demons2  
  • 删除NameSpace
kubectl delete ns test1  
kubectl deltete -f **.yml

最小管理单元pod

pod 是容器的封装
查看
kubectl get pods --ns default
创建
kubectl apply -f **.yml

apiVersion: v1 
kind: Pod
metadata:
  name: pod1
spec:
  containers:
  - name: nginx-pod
    image: nginx:latest
    ports:
    - name:nginxport
      containerPort:80
kubectl get pods -o wide   
生产环境最好不要直接访问pod  
删除pod    
kubectl  delete pods pods1  
yml文件删除  
kubectl delete -f **.yml  

k8s 核心概念controller 控制器

loop 方式监控pod 状态 如果发生删除会重新拉起

  • 控制器作用
对应用`运行的资源对象监控  
出现问题 重新拉起 达到期望状态  
  • 控制器分类 官网介绍更全
可以自定义 常见控制器   
Deployment  声明式 更新控制器  发布无状态应用 
ReplicaSet  副本集控制器  对Pod 进行规模扩大杰少
StatefulSet  有状态副本集 mysql  用于发布有状态应用  
DaemonSet   每一个Node 上运行一个副本  用于发布监控或日志收集  
Job 运行一次性作业任务  
CronJob  运行周期性任务  
  • Deployment 控制器介绍、
命令创建   默认 Deployment  
kubectl run nginx-app --image=nginx:latest -image-pull-policy-IfNotPresent --replicas=2   //2个pod运行 
kubectl get deployment.apps
kubectl get replicaset.apps
------------------------ 
apiVersion: apps/v1 s 
kind: Deployment
metadata:
  name: nginx-app2
spec:
 replicas: 1 #副本数量
 selector: #标签选择器  与pod 进行关联 
   matchLabels:
     app: nginx
 template: #pod 模板 
   metadata:
     labels:
       app: nginx
   spec:
      containers:
       - name: nginx-app2container
         image: nginx:latest
         imagePullPolicy: IfNotPresent
         ports:
         - name: nginxapp2
           containerPort: 80
  • 删除应用
    带有控制器的Pod 不能直接删除 会自动拉起

kubectl get deployment.apps
kubectl delete deployment.apps **

k8s 核心概念 service 服务

    不是实体服务 是一条iptables 或者 ipvs 的转发规则  
    通过service为pod客户端提供访问pod 的方法=客户端访问pod的入口  
    service 同pod 标签与pod 关联  
  • service 类型
-- ClusterIP  
 默认分配一个集群内部可以访问的虚拟ip 
-- NodePort  
在每一个Node 上分配一个端口作为外部访问  
-- oadBalancer  
工作在特定的 云服务上  aws  openstart  
-- ExternalName  
表示把几圈外部服务引入到集群内部来实现进群内部pod 与集群外部的服务进行通信  
- service 常用参数  
 port  访问service使用的端口  
 targetPort  pod 中容器端口 
 NodePort 通过 Node 实现外网访问k8s 内service (30000-32767)
  • 创建 service
命令行创建 默认创建为ClusterIp  
先创建应用  
kubectl run nginx-app --image=nginx:latest --image-pull-policy=IfNotPresent --replicas=1  
创建service  
kubectl expose deployment.apps nginx-app --type=ClusterIP --target-port=80 --port=80


  • yml 创建service
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-app2
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginapp2
        image: nginx:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-app2
spec:
  type: ClusterIP
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  • 查看
    kubectl get service

kubectl get endpoints

  • 创建 NodePort 类型的service 只需要修改type即可
  • service 自带负载均衡 均匀访问多个 pod

防火墙,其实说白了讲,就是用于实现Linux下访问控制的功能的,它分为硬件的或者软件的防火墙两种。无论是在哪个网络中,防火墙工作的地方一定是在网络的边缘。而我们的任务就是需要去定义到底防火墙如何工作,这就是防火墙的策略,规则,以达到让它对出入网络的IP、数据进行检测。

目前市面上比较常见的有3、4层的防火墙,叫网络层的防火墙,还有7层的防火墙,其实是代理层的网关。

对于TCP/IP的七层模型来讲,我们知道第三层是网络层,三层的防火墙会在这层对源地址和目标地址进行检测。但是对于七层的防火墙,不管你源端口或者目标端口,源地址或者目标地址是什么,都将对你所有的东西进行检查。所以,对于设计原理来讲,七层防火墙更加安全,但是这却带来了效率更低。所以市面上通常的防火墙方案,都是两者结合的。而又由于我们都需要从防火墙所控制的这个口来访问,所以防火墙的工作效率就成了用户能够访问数据多少的一个最重要的控制,配置的不好甚至有可能成为流量的瓶颈
本次介绍iptables防火墙

iptables防火墙说明及工作原理
iptables防火墙包含四个表和五个链,分别为

四个表分别为:

Filter表(真正的防火墙功能)
Nat表(负责数据包的改写)
Mangle表(路由标记)
raw表(禁止数据包的连接跟踪,用于提高性能)

五个链分别为:
INPUT(进入防火墙)
OUTPUT(离开防火墙)
FORWARD(流经防火墙)
PREROUTING(数据包到达防火墙之前进行路由判断)
POSTROUTING(数据包离开防火墙时进行的路由判断)

3.表和链的包含情况说明

Filter表包含: INPUT、OUTPUT、FORWARD;
Nat表包含: OUTPUT、PREROUTING、POSTROUTING;
Mangle表包含: INPUT、OUTPUT、FORWARD、PREROUTING、POSTROUTING;
Raw表包含: OUTPUT、PREROUTING;

4.iptables防火墙的工作原理说明

1、iptables防火墙是一层层过滤的,实际是按照配置规则的顺序从上到下,从前到后进行过滤的。
2、如果匹配上规则,即明确表明是阻止还是通过,此时数据包就不在向下匹配新规则了。
3、如果所有规则中没有明确表示是阻止还是通过这个数据包,也就是没有匹配上规则,向下进行匹配,直到匹配到默认规 则到明确阻止还是通过。
4、防火墙的默认规则是对应链的所有规则执行完才会执行的。
注:防火墙规则执行顺序默认是从前到后,(从上到下)依次执行,遇到匹配的规则就不在继续向下检查,只有遇到不匹配的规则才会继续向下进行匹配

Iptables防火墙使用及规则配置

iptables命令常用参数
很多参数请通过man iptables或iptables --help来查看

-n:以数字的方式显示ip,它会将ip直接显示出来,如果不加-n,则会将ip反向解析成主机名。
-L(大写)列表 例:iptbles -nL 查看iptables规则
--line-number显示规则的序号 iptables -nL --line-number (可以根据序号删除规则)
-D 删除规则 (查到规则序号后、指定链、指定序号删掉) 例: iptables -D INPUT 1 (指顶删除INPUT链的第一条规则、默认是FILTER表、如果是其他的表需要-t指定表)
-F(大写)清除所有规则,不会处理默认的规则
-X(大写)删除用户自定义的链
-Z(大写)清除链的计数器
-A (大写)添加规则到指定链的结尾
-I (大写) 添加规则到指定链的开头
-P (大写)设置默认策略的(设定默认门是关着的还是开着的)
-t 指定表(默认是filter表) 例:iptables -t filter -A INPUT -p tcp --dport 443 -j DROP #指定在filter表的input链的tcp协议443端口的请求丢弃
-p 匹配指定协议 (all(所有) 、tcp、udp、icmp(ping等)、默认all)
--dport 目的端口(对本地的端口做什么)
--sport 源端口(从那个端口连接过来的)
-j 处理的行为 {DROP(丢弃)、ACCEPT(接受)、REJECT(拒绝)、ACCEPT(接受)
-s 指定源ip地址
-d 目的地址
-i 匹配进入的网卡接口eth0或者eth1进行控制
-o 匹配出去的网卡借口

配置一个生产中只开启443端口的防火墙规则
说明:这里配置的防火墙规则只开启443端口(https),
1.首先清除防火墙的默认规则

iptables -F

iptables -X

iptables -Z

2.允许自己的网段连接服务器

iptables -A INPUT -p tcp -s 10.0.0.0/24 -j ACCEPT
允许自己的回环接口进出:
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
3.设置默认规则:

iptables -P INPUT DROP #忽略进入的请求
iptables -P FORWARD DROP #忽略要通过
iptables -P OUTPUT ACCEPT #允许出去的请求
4.配置规则

iptables -A INPUT -s 124.43.62.96/27 -p all -j ACCEPT #允许办公室的ip段连接

iptables -A INPUT -s 192.168.1.0/24 -p all -j ACCEPT #允许其他机房的网段链接

iptables -A INPUT -p tcp --dport 443 -j ACCEPT #允许业务端口对外提供链接

iptables -A INPUT -p icmp -m icmp --icmp-type any -j ACCEPT #允许所有人ping

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT #允许关联包通过
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
至此防火墙就配完了。以上命令是在命令行执行的没有永久生效,重启主机就失效了:
永久保存的方法:

services iptables save

就保存到/etc/sysconfig/iptables中了
以后维护iptables就可以通过编辑/etc/sysconfig/iptables来更改规则了。
CentOS 7自带的防火墙是firewalld,需要下载iptables:

yum install -y iptables-services

发现问题

据说mariadb和mysql 90% 相似度,本地使用docker 起了个容器 挂载数据到本地的时候居然报错了

[ERROR] InnoDB: The Auto-extending innodb_system data file './ibdata1' is of a different size 0 pages than specified in the .cnf file: initial 768 pages, max 0 (relevant if non-zero) pages!

查询问题

和 mysql 一样的配置为什么会报错的,一脸懵逼??? ./ibdata1
查询了各大资源后发现可能是 Docker for windows 的共享文件系统或MariaDB本身中的bug!!!

解决问题

最后经过苦苦测试 终于找到了一个可行的解决方案
下面解释一下关键配置

  • ibdata1是InnoDB的共有表空间,默认情况下会把表空间存放在一个文件ibdata1中
  • innodb_flush_method 则确定日志及数据文件如何write、flush
  • innodb_flush_method可以取如下值:fdatasync, O_DSYNC, O_DIRECT 实验选项littlesync和nosync
  • innodb_use_native_aio 该选项仅适用于Linux系统,默认情况下处于启用状态。在其他类Unix系统上,InnoDB仅使用同步I/O. - 从历史上看,InnoDB仅在Windows系统上使用异步I/O. 在Linux上使用异步I/O子系统需要libaio库
  • Binary Log 简称 Binlog 即 二进制日志文件,这个文件记录了mysql所有的 DML 操作。
  • 通过 Binlog 日志我们可以做数据恢复,做主主复制和主从复制等等。

下面是的我的 docker-compose.yml 和 配置

dockerFile
FROM mariadb:latest

LABEL maintainer="Mahmoud Zalt <mahmoud@zalt.me>"

COPY my.cnf /etc/mysql/conf.d/my.cnf



CMD ["mysqld"]

EXPOSE 3306
docker-compose.yml
    mariadb:
      build: ./mariadb
      volumes:
        - ./mariadb/data:/var/lib/mysql
 
      ports:
        - "3306:3306"
      environment:
        - MYSQL_DATABASE=default
        - MYSQL_USER=default
        - MYSQL_PASSWORD=default
        - MYSQL_ROOT_PASSWORD=root
      networks:
        - backend
      command:
        mysqld --innodb-flush-method=littlesync --innodb-use-native-aio=OFF --log_bin=ON
mariadb 配置
[mysqld]
innodb_flush_method=littlesync
innodb_use_native_aio=OFF
log_bin=ON

安装包 (win10并开启虚拟化)

https://download.docker.com/win/stable/Docker%20for%20Windows%20Installer.exe

git 仓库

git@github.com:weiyixi/docker_study.git
目录说明
  1. nginx 站点配置在 ./docker-lnmp/nginx/site (修改后重启nginx容器生效)
  2. php-fpm 容器中/var/www/目录挂载本地docker-lnmp的上层目录(.env中 APPLICATION=../)
  3. 需要加扩展在对应得dockerfile 中修改

1.修改配置

env-example  复制为 .env
//window需要修改
DOCKER_SYNC_STRATEGY=unison
//php版本修改默认7.2
PHP_VERSION=72

2.基本操作

首先到docker-lnmp目录下

1.构建  docker-compose build  nginx php-fpm  redis  mysql 
2.开启  docker-compose up -d  nginx  redis  mysql 
3.关闭  docker-compose down
4.查看运行中容器  docker  ps
5.进入容器中   docker exec -it 对应的CONTAINER_ID  bash

3.扩展

1.已经定义了一批扩展可在 .env中开启 true开启 false 关闭
2.未定义的需要修改dockerfile安装
3.修改后需要重新build 开启才会生效

适用于对docker有一定了解的朋友,小白请先仔细阅读官方文档!
作为应用程序,我们通常需要依赖于多种外部服务,比如数据库、缓存服务等等。
Docker-compose就是在Docker容器的基础上,提供了统一的容器编排语言,可以让你更轻松的利用Docker构建你的应用环境。

docker-compose.yml文件语法语法

image 使用的镜像
build 指定Dockerfile构建
command 启动执行命令
links 链接其他容器    
ports 端口映射
expose 暴露端口
volumes 挂载路径
volumes_from 从容器挂载
environment 环境变量
  1. 编写dockerfile(自定义镜像)
  2. 编写docker-compose.yml(可以不依赖Dockerfile 使用官方镜像)

常用命令

构建容器 docker-compose up -d
查看容器 docker-compose ps
进入容器 docker exec -it 容器名 /bin/bash
关闭所有 docker-compose  down

php-fpm Dockerfile 示例 可以自定义扩展

FROM php:7.1-fpm-alpine

# apk
RUN apk --update add \
        autoconf \
        build-base \
        linux-headers \
        libaio-dev \
        zlib-dev \
        curl \
        git \
        subversion \
        freetype-dev \
        libjpeg-turbo-dev \
        libmcrypt-dev \
        libpng-dev \
        libtool \
        libbz2 \
        bzip2 \
        bzip2-dev \
        libstdc++ \
        libxslt-dev \
        openldap-dev \
        imagemagick-dev \
        make \
        unzip \
        wget \
        libmemcached-dev

# PHP Core Extensions
RUN docker-php-ext-install \
        bcmath \
        pdo_mysql \
        mysqli \
        pcntl \
    && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
    && docker-php-ext-install gd

# PECL Extensions
RUN pecl install redis-4.2.0 \
    && pecl install mongodb-1.5.3 \
    && pecl install memcached-3.1.3 \
    && pecl install swoole-4.3.1 \
    && docker-php-ext-enable redis mongodb memcached swoole

# Delete
RUN apk del build-base \
        linux-headers \
        libaio-dev \
    && rm -rf /var/cache/apk/* \
    && mkdir /data \
    && chmod -R 777 /data

VOLUME /var/www
WORKDIR /var/www

EXPOSE 9000
CMD ["php-fpm"]

docker-compose.yml示例

version: "3.0"
services:
  nginx:
    image: nginx:alpine
    ports: 
      - 80:80
      - 443:443
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/conf.d:/etc/nginx/conf.d
      - ../:/var/www

  php-fpm:
    build: ./php-fpm
    ports:
        - 9000:9000
    volumes:
      - ./php-fpm/php.ini:/usr/local/etc/php/php.ini
      - ./php-fpm/www.conf:/usr/local/etc/php-fpm.d/www.conf
      - ../:/var/www

  mysql:
    image: mysql:5.7
    ports:
      - 3306:3306
    volumes:
      - ./mysql/data:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=123456

  redis:
    image: redis:5.0-alpine
    ports:
      - 6379:6379
    volumes:
      - ./redis/data:/data
      #- ./redis/redis.conf:/usr/local/etc/redis/redis.conf

  mongo:
    image: mongo
    ports: 
      - 27017:27017
    volumes:
      - ./mongo/data:/data/db
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: 123456