前期准备

虚拟机准备:

  1. hubo-11
    Vmware:192.168.116.11
  2. hubo-12
    Vmware:192.168.116.12
  3. hubo-21
    Vmware:192.168.116.21
  4. hubo-22
    Vmware:192.168.116.22
  5. hubo-200
    Vmware:192.168.116.200

系统环境准备

  1. 主机名修改

    hostnamectl set-hostname hubo-11.host.com
    
  2. SELinux 状态配置:

    说明:SELinux 是 2.6 版本的 Linux 内核中提供的强制访问控制(MAC)系统。【推荐

    # 查看SELinux状态,enforcing 表示开启状态
    getenforce
    
    # 关闭 SELinux,将 SELINUX 设置为 disabled
    vi /etc/selinux/config
    

    在这里插入图片描述
    注:需要重启生效

  3. 防火墙配置

    # 查看防火墙状态
    firewall-cmd --state
    # 暂时先关闭防火墙
    systemctl stop firewalld
    # 禁止开机自启动
    systemctl disable firewalld.service 
    
  4. 配置安装epel源和base源

    yum install epel-release -y
    
  5. 安装一些基本工具:

    yum install wget net-tools telnet tree nmap sysstat lrzsz dos2unix bind-utils -y
    

    工具功能简单说明:

    工具用途
    wget通过 url 获取网络资源
    net-tools
    telnet远程连接工具
    tree
    nmap
    sysstat
    lrzsz
    dos2unix
    bind-utils

整体架构设计

自建DNS服务 — bind工具

注:在虚拟主机 192.168.116.11 上安装 DNS 服务
nslookup www.baidu.com 可以产看域名映射的ip地址,nslookup 是 bind-utils 工具中的一个指令

  1. 安装 bind
    yum install bind -y
    
  2. 修改配置
    1. 修改主配置文件 /etc/named.conf

      vi /etc/named.conf 
      

      主要修改内容:
      listen-on 监听配置,监听本机网络IP地址 端口53
      allow-query 允许查询配置,运行网络内所有主机查询
      forwarders 上级DNS服务,使用虚拟机的网关地址
      recursion 使用递归解析方式解析域名
      dnssec-enable 和 dnssec-validation 实验环境暂时关闭节约性能
      在这里插入图片描述

      修改完成后可以使用:named-checkconf 命令查看配置文件格式是否正确

    2. 配置区域配置文件 /etc/named.rfc1912.zones

      注:该文件会被主配置文件引入:
      在这里插入图片描述

      vi /etc/named.rfc1912.zones
      

      在配置文件结尾追加两个域,一个主机域,一个业务域名,内容如下:

      注意空行空格tab等分隔符,要求严格,配置完成后可以用 named-checkconf filename 检查

      zone "host.com" IN {
              type master;
              file "host.com.zone";
              allow-update { 192.168.116.11; };
      };
      
      zone "k8s.com" IN {
              type master;
              file "k8s.com.zone";
              allow-update { 192.168.116.11; };
      };
      
    3. 编辑区域数据文件

      添加主机域配置文件:

      vi /var/named/host.com.zone
      

      /var/named/host.com.zone 文件内容:

      $ORIGIN host.com.
      $TTL 600        ;10 minutes
      @       IN SOA dns.host.com. dnsadmin.host.com. (
                      2021081501    ; serial
                      10800         ; refresh (3 hours)
                      900           ; retry (15 minutes)
                      604800        ; expire (1 week)
                      86400         ; minimum (1 day)
                      )
                      NS      dns.host.com.
      $TTL 60 ; 1 minute
      dns             A       192.168.116.11
      HUBO-11         A       192.168.116.11
      HUBO-12         A       192.168.116.12
      HUBO-21         A       192.168.116.21
      HUBO-22         A       192.168.116.22
      HUBO-200        A       192.168.116.200
      
      

      添加业务域配置文件

      vi /var/named/k8s.com.zone
      

      /var/named/k8s.com.zone 文件内容:

      $ORIGIN k8s.com.
      $TTL 600        ;10 minutes
      @       IN SOA dns.host.com. dnsadmin.host.com. (
                      2021081501    ; serial
                      10800         ; refresh (3 hours)
                      900           ; retry (15 minutes)
                      604800        ; expire (1 week)
                      86400         ; minimum (1 day)
                      )
                      NS      dns.k8s.com.
      $TTL 60 ; 1 minute
      dns             A       192.168.116.11
      
    4. 启动 DNS 服务:

      systemctl start named
      ## 查看启动后的监听
      netstat -luntp | grep 53
      

      在这里插入图片描述
      测试写是否可以正确解析:dig -t A hubo-21.host.com @192.168.116.11 +short

      注:在启动是出错:
      在这里插入图片描述
      配置文件有问题,通过命令检查:named-checkconf -z /etc/named/named.conf
      在这里插入图片描述
      发现之前在区域配置文件中配置的 k8s.com 域对应的数据文件写错了:
      在这里插入图片描述
      解决:该配置或者改文件名

    5. 修改网卡配置并重启

      每一台机器都要修改DNS服务地址,改成192.168.116.11
      vi /etc/sysconfig/network-scripts/ifcfg-ens33
      并添加主机域访问时自动搜索,这样访问主机域时不用写后面的主机域(host.com)
      vi /etc/resolv.conf 添加一行 search host.com
      在这里插入图片描述
      重启网卡:
      systemctl restart network
      通过主机域ping其他主机测试:
      ping hubo-200

    6. 修改本机虚拟机网络的首先DNS
      在这里插入图片描述
      高级设置中修改自动跃点数:
      在这里插入图片描述
      ping hubo-200.host.com 测试一下。

证书签发环境 —— 自签证书之 CFSSL

注:也可以用openssl
证书签发服务安装在:192.168.116.200 虚拟主机上

证书签发工具安装:

版本:1.2

  1. cfssl
  2. cfssl-json
  3. cfssl-certinfo

如果没有互联网环境可以下载二进制文件然后传到虚拟机中

有互联网环境就直接用wget命令从网上获取:

# 将软件包下载到 /usr/bin 目录下
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -O /usr/bin/cfssl
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -O /usr/bin/cfssl-json
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -O /usr/bin/cfssl-certinfo
# 添加可执行权限
chmod +x /usr/bin/cfssl*
根证书制作
  1. 创建根证书 json 配置文件: ca-csr.json

    mkdir -p /opt/certs
    vi /opt/certs/ca-csr.json
    

    ca-csr.json文件内容:

    {
            "CN": "HuBoEdu",
            "hosts": [
            ],
            "key": {
                    "algo": "rsa",
                    "size": 2048
            },
            "names": [
                    {
                            "C": "CN",
                            "ST": "liaoning",
                            "L": "shenyang",
                            "O": "edu",
                            "OU": "development"
                    }
            ],
            "ca": {
                    "expiry": "17520h"
            }
    }
    

    文件内容说明:

    • CN : Common Name,浏览器使用该字段验证网站是否合法,一般用域名
    • key:密钥相关配置,algo 表示加密算法
    • names:基本名称信息,C-国家,ST-州省,L-地区城市,O-组织机构,OU-组织单位名称或部门
    • ca:证书配置,expiry表示过期时间
  2. 制作根证书

    cfssl gencert -initca ca-csr.json | cfssl-json -bare ca
    

    签发后查看: 在这里插入图片描述

部署 docker 容器引擎环境

k8s依赖于容器引擎
计划在 HUBO-21 ,HUBO-22 ,HUBO-200 三台虚拟主机部署 docker-ce 容器引擎

  1. 在线安装可参考:
  2. 离线二进制包安装:
    1. 下载对应的二进制文件
      docker历史版本下载地址
      也可以在其他又网络的主机上下载:

      curl -O https://download.docker.com/linux/static/stable/x86_64/docker-18.06.3-ce.tgz
      
    2. 编辑安装脚本:install-docker.sh

      #!/bin/sh
      
      usage(){
        echo "Usage: $0 FILE_NAME_DOCKER_CE_TAR_GZ"
        echo "       $0 docker-17.09.0-ce.tgz"
        echo "Get docker-ce binary from: https://download.docker.com/linux/static/stable/x86_64/"
        echo "eg: wget https://download.docker.com/linux/static/stable/x86_64/docker-17.09.0-ce.tgz"
        echo ""
      }
      SYSTEMDDIR=/usr/lib/systemd/system
      SERVICEFILE=docker.service
      DOCKERDIR=/usr/bin
      DOCKERBIN=docker
      SERVICENAME=docker
      
      if [ $# -ne 1 ]; then
        usage
        exit 1
      else
        FILETARGZ="$1"
      fi
      
      if [ ! -f ${FILETARGZ} ]; then
        echo "Docker binary tgz files does not exist, please check it"
        echo "Get docker-ce binary from: https://download.docker.com/linux/static/stable/x86_64/"
        echo "eg: wget https://download.docker.com/linux/static/stable/x86_64/docker-17.09.0-ce.tgz"
        exit 1
      fi
      
      echo "##unzip : tar xvpf ${FILETARGZ}"
      tar xvpf ${FILETARGZ}
      echo
      
      echo "##binary : ${DOCKERBIN} copy to ${DOCKERDIR}"
      cp -p ${DOCKERBIN}/* ${DOCKERDIR} >/dev/null 2>&1
      which ${DOCKERBIN}
      
      echo "##systemd service: ${SERVICEFILE}"
      echo "##docker.service: create docker systemd file"
      cat >${SYSTEMDDIR}/${SERVICEFILE} <<EOF
      [Unit]
      Description=Docker Application Container Engine
      Documentation=http://docs.docker.com
      After=network.target docker.socket
      [Service]
      Type=notify
      EnvironmentFile=-/run/flannel/docker
      WorkingDirectory=/usr/local/bin
      ExecStart=/usr/bin/dockerd \
                      -H tcp://0.0.0.0:4243 \
                      -H unix:///var/run/docker.sock \
                      --selinux-enabled=false \
                      --log-opt max-size=1g
      ExecReload=/bin/kill -s HUP $MAINPID
      # Having non-zero Limit*s causes performance problems due to accounting overhead
      # in the kernel. We recommend using cgroups to do container-local accounting.
      LimitNOFILE=infinity
      LimitNPROC=infinity
      LimitCORE=infinity
      # Uncomment TasksMax if your systemd version supports it.
      # Only systemd 226 and above support this version.
      #TasksMax=infinity
      TimeoutStartSec=0
      # set delegate yes so that systemd does not reset the cgroups of docker containers
      Delegate=yes
      # kill only the docker process, not all processes in the cgroup
      KillMode=process
      Restart=on-failure
      [Install]
      WantedBy=multi-user.target
      EOF
      
      echo ""
      
      systemctl daemon-reload
      echo "##Service status: ${SERVICENAME}"
      systemctl status ${SERVICENAME}
      echo "##Service restart: ${SERVICENAME}"
      systemctl restart ${SERVICENAME}
      echo "##Service status: ${SERVICENAME}"
      systemctl status ${SERVICENAME}
      
      echo "##Service enabled: ${SERVICENAME}"
      systemctl enable ${SERVICENAME}
      
      echo "## docker version"
      docker version
      
      
    3. 授予可执行权限并执行
      chmod +x install-docker.sh
      ./install-docker.sh docker-18.06.3-ce.tgz 2>&1 |tee install.log

    4. 检验 docker versiondocker infodocker images

    5. 配置各 docker 的网络 bip,便于区分
      修改配置文件:daemon.json

      配置文件位置:/etc/docker/daemon.json,如果没有就新建一个

      daemon.json内容:

      {
              "graph": "/data/docker",
              "storage-driver": "overlay2",
              "insecure-registries": ["registry.access.redhat.com","quay.io","harbor.hubo.com"],
              "registry-mirrors": ["https://q2gr04ke.mirror.aliyuncs.com"],
              "bip": "172.7.21.1/24",
              "live-restore": true
      }
      

      注:bip 根据各个主机 ip 做响应的配置
      注:"exec-opts": ["native.cgroupdriver=systemd"],` 这个选项配置有问题,加了这个之后容器运行不起来,导致后面启动 Pod 出错。先使用默认的 cgroupfs ,在后面 kubelet 配置 cgroupRoot 参数时也要选择 cgroupfs。

    6. 重启docker :systemctl restart docker

    7. 查看 docker0 网卡信息:ip addr

搭建一个私有 docker 镜像仓库 —— harbor(离线部署版)

在 hubo-200 虚拟主机中搭建

官方地址:https://goharbor.io/
下载地址:https://github.com/goharbor/harbor/releases

下载的时候下载 harbor-offline-installer-vx.x.x.tgz 版本(离线安装版本)
harbor-offline-installer-v2.3.1.tgz
下载后上传到:192.168.116.200 虚拟主机的 /opt/application-src

有网可以直接在 192.168.116.200 上用 wget 命令获取:
wget https://github.com/goharbor/harbor/releases/download/v2.3.1/harbor-offline-installer-v2.3.1.tgz

在这里插入图片描述

解压到 /opt 目录下:
tar xf harbor-offline-installer-v2.3.1.tgz -C /opt/
在这里插入图片描述
将 /etc/harbor 目录加上版本号并建立软连接(便于版本管理):

# /opt 目录下
mv harbor/ harbor-v2.3.1
ln -s /opt/harbor-v2.3.1/ /opt/harbor

在这里插入图片描述
修改配置文件/opt/harbor/harbor.yml

# 在 /opt/harbor 目录下
# 拷贝模板配置文件
cp harbor.yml.tmpl harbor.yml
# 编辑配置文件
vi harbor.yml

修改内容:

  1. 将 hostname 配置到之前设计的业务域上
    hostname: harber.k8s.com

    原本想设置的是:harbor.k8s.com ,但是写出了,导致了后面出现的问题,但是可以通过其他方式解决,详细见后面的内容。

  2. 修改 htpp 端口,默认是 80,改成 180(防止将来使用 80 时被占用)

    http:
      port: 180
    
  3. 修改默认的管理原密码
    harbor_admin_password: Harbor12345

  4. 修改日志相关配置

    # Log configurations
    log:
      # options are debug, info, warning, error, fatal
      level: info
      # configs for logs in local storage
      local:
        # Log files are rotated log_rotate_count times before being removed. If count is 0, old versions are removed rather than rotated.
        rotate_count: 50
        # Log files are rotated only if they grow bigger than log_rotate_size bytes. If size is followed by k, the size is assumed to be in kilobytes.
        # If the M is used, the size is in megabytes, and if G is used, the size is in gigabytes. So size 100, size 100k, size 100M and size 100G
        # are all valid.
        rotate_size: 200M
        # The directory on your host that store log  日志保存地址
        location: /data/harbor/logs
    
  5. 修改默认数据存储目录:

    # The default data volume
    data_volume: /data/harbor
    
  6. mkdir -p /data/harbor/logs 创建相应的目录

  7. 遇到的问题:安装时最后出现 https 相关的错误 没有设置ssl证书

    prepare base dir is set to /opt/harbor-v2.3.1
    Error happened in config validation…
    ERROR:root:Error: The protocol is https but attribute ssl_cert is not set
    在这里插入图片描述

    所以需要先把 https 相关的配置注释掉。

harbor 是一个基于 docker 引擎的单机编排的软件,需要依赖 docker-compose 。

在 hubo-200 上安装 docker-compose :

  1. 在线安装:
    yum install docker-compose -y

  2. 离线安装
    下载离线包:https://github.com/docker/compose/releases
    docker-compose-Linux-x86_64
    放到 /opt/application-src/ 目录下
    将刚下载的 docker-compose-Linux-x86_64 复制到 /usr/local/bin 并重命名为 docker-compose :

    # 在 /opt/application-src/ 目录下执行
    # 复制重命名
    cp docker-compose-Linux-x86_64 /usr/local/bin/docker-compose
    # 可执行权限
    chmod +x /usr/local/bin/docker-compose
    # 检查是否安装成功
    docker-compose -version
    

安装 harbor:(到前面的 /opt/harbor/ 目录下执行安装文件)
./install.sh
在这里插入图片描述

启动过程中遇到的问题:

  1. https 问题在本节修改配置中第7条说明
  2. ERROR: Failed to Setup IP tables: Unable to enable SKIP DNAT rule
    原因:之前关闭防火墙没有重启 docker
    解决:service docker restart

启动完成查看容器:在这里插入图片描述

设置 harbor 开机启动:

[root@hubo-200 harbor]# vi /etc/rc.d/rc.local  # 增加以下内容
# start harbor
cd /opt/harbor
/usr/docker-compose stop
/usr/docker-compose start

宿主机web访问:http://hubo-200.host.com:180/在这里插入图片描述
配置业务域访问
这里访问使用的是自建DNS中设置的主机域,为了使用业务域访问,需要配置 hubo-11 上的DNS:

# 在 hubo-11(192.168.116.11)主机上,修改业务域配置
vi /var/named/k8s.com.zone

在业务域中增加一条:
harbor A 192.168.116.200
另外:序列号需要手动的加一
在这里插入图片描述
修改完成后重启服务

systemctl restart named.service
# 测试一下
host harbor.k8s.com

浏览器中可以用:http://harbor.k8s.com:180 访问 harbor 控制台

反向代理 harbor
为了用 80 端口访问 harbor 需要在 hubo-200 上装 Nginx 做一个反向代理:

  1. 在线安装 Nginx : yum install nginx -y
  2. 离线安装Nginx:
    软件包下载地址:http://nginx.org/packages/centos/7/x86_64/RPMS/
    nginx-1.16.1-1.el7.ngx.x86_64.rpm
    下载上传到 /opt/application-src/ 目录下
    安装命令:yum install -y nginx-1.16.1-1.el7.ngx.x86_64.rpm

添加 Nginx 配置文件:vi /etc/nginx/conf.d/harbor.conf 内容如下:

server {
    listen       80;
    server_name  harbor.k8s.com;
    client_max_body_size 1000m;
    location / {
        proxy_pass http://127.0.0.1:180;
    }
}

启动与开机自启动:

## 启动
service nginx start
#或者
systemctl start nginx
## 设置开机自启动
systemctl enable nginx.service

至此,在浏览器中已经可以直接使用 http://harbor.k8s.com/ 访问 harbor 。
在完成整个项目部署后会正对防火墙进行配置,会关闭 hubo-200 主机 180 端口的对外访问。

测试私有仓库:
访问 http://harbor.k8s.com/ 登录,新建一个项目:public
向私有仓库 push 第一个镜像:

  1. 先给已有镜像打标签 tag
    docker tag nginx:1.7.9 harbor.k8s.com/public/nginx:v1.7.9

    nginx:1.7.9 是从公网拉的:docker pull nginx:1.7.9

  2. 登录私有仓库:docker login
    docker login -u admin harbor.k8s.com
  3. 推送
    docker push harbor.od.com/public/nginx:v1.7.9
  4. 退出
    docker logout

镜像来源可以从公网 pull 的,如果没有网,那就从别的地方上创导宿主机然后 docker load,或者在宿主机上构建。

执行 docker login harbor.k8s.com 时遇到问题:

Error response from daemon: Get http://harbor.k8s.com/v2/: Get http://harbor.k8s.com:180/service/token?account=admin&client_id=docker&offline_token=true&service=habor-registry: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)

错误分析:docker使用Http请求并且是Get,访问 http://harbor.k8s.com:180 ,说明 DNS 解析是正常的,但是代理出了问题,正常应该是 180 端口通过 Nginx 交给了 80 端口代理,命令缺省,说明访问的是 80 端口,而错误日志却显示 180,说明 Nginx 应该也没有问题,至少是代理了, 所以需要检查一下 harbor 的配置:发现一个 external_url 的配置,以及其官网:

# Uncomment external_url if you want to enable external proxy
# And when it enabled the hostname will no longer used
# external_url: https://reg.mydomain.com:8433

如果要启用外部代理,请取消 external_url 的注释
当它启用时,主机名将不再使用

如果取消这个注释,那么主机名就不会生效了,于是检查了一下配置的主机名,果然写错了,写的 harber.k8s.com ,但是使用的是 harbor.k8s.com ,harbor认为 harbor.k8s.com 是一个 external_url ,但是配置文件中又没有将这个配置打开,所以 harbor 访问时会出错

解决:

  1. 把主机名写正确,或者打开 external_url 配置,地址设置为 http://harbor.k8s.com:80

  2. 删除所有 harbor 相关的容器,停止所有 harbor 服务

    ## 在 /opt/harbor/ 目录下
    docker-compose down
    
  3. 删除之前安装 harbor 的配置目录

    ## 在 /opt/harbor/ 目录下
    rm -rf ./common/config
    
  4. 重新安装执行命令

    ## 在 /opt/harbor/ 目录下
    ./install.sh
    

部署 etcd 存储服务集群

etcd 目标是构建一个高可用的分布式键值(key-value)数据库。etcd内部采用 raft 协议作为一致性算法,基于Go语言实现。

优势:

  1. 简单:安装配置简单,而且提供了HTTP API进行交互,使用也很简单
  2. 安全:支持SSL证书验证
  3. 快速:根据官方提供的benchmark数据,单实例支持每秒2k+读操作
  4. 可靠:采用raft算法,实现分布式系统数据的可用性和一致性

etcd 详细介绍

目标,在 hubo-12,hubo-21,hubo-22 上部署 etcd 集群

主机名角色IP
hubo-12etcd lead192.168.116.12
hubo-21etcd follow192.168.116.21
hubo-22etcd follow192.168.116.22

注: 以 hubo-12 主 etcd节点部署为例,另外两个节点类似。

下载 etcd

etcd 地址:https://github.com/etcd-io/etcd/releases
本文使用版本: etcd-v3.5.0-linux-amd64.tar.gz

下载后放到/opt/application-src/目录下
解压:tar -xf etcd-v3.5.0-linux-amd64.tar.gz
移动到/opt并重命名:mv etcd-v3.5.0-linux-amd64 /opt/etcd-v3.5.0
创建软连接:ln -s /opt/etcd-v3.5.0 /opt/etcd
查看结果:ll /opt/etcd

创建 etcd 用户
useradd -s /sbin/nologin -M etcd
创建一些目录:
mkdir -p /opt/etcd/certs /data/etcd /data/logs/etcd-server

至此,三台机器都完成了下载解压创建用户和目录的步骤。(目录和用户是后面需要使用的)

为 etcd 服务签发证书:

使用 hubo-200 虚拟主机上的 cfssl 证书签发服务制作 etcd 需要的证书,并分发到三台 etcd 虚拟主机。

注:在hubo-200主机上操作

创建根证书配置文件 /opt/certs/ca-config.json

{
    "signing": {
        "default": {
            "expiry": "175200h"
        },
        "profiles": {
            "server": {
                "expiry": "175200h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "server auth"
                ]
            },
            "client": {
                "expiry": "175200h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "client auth"
                ]
            },
            "peer": {
                "expiry": "175200h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "server auth",
                    "client auth"
                ]
            }
        }
    }
}
profiles 说明:
	server 表示服务端连接客户端时携带的证书,用于客户端验证服务端身份
	client 表示客户端连接服务端时携带的证书,用于服务端验证客户端身份
	peer 表示相互之间连接时使用的证书,如etcd节点之间验证
expiry: 过期时间,有效时长

创建 etcd 证书配置:/opt/certs/etcd-peer-csr.json

{
    "CN": "k8s-etcd",
    "hosts": [
        "192.168.116.11",
        "192.168.116.12",
        "192.168.116.21",
        "192.168.116.22"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "ST": "liaoning",
            "L": "shenyang",
            "O": "edu",
            "OU": "development"
        }
    ]
}

host: 所有可能的etcd服务器添加到host列表

签发 ectd-peer 证书:

## 在 /opt/certs/ 目录下
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=peer etcd-peer-csr.json | cfssl-json -bare etcd-peer

在这里插入图片描述

hubo-200 证书签发服务向 etcd 服务分发证书

## 
for i in 12 21 22;do scp ca.pem etcd-peer.pem etcd-peer-key.pem hubo-${i}:/opt/etcd/certs/ ;done

在这里插入图片描述
在这里插入图片描述

启动 etcd 服务

创建 etcd 的启动脚本

在三台待安装 etcd 服务的虚拟主机中分别创建 /opt/etcd/etcd-server-startup.sh 启动脚本

vi /opt/etcd/etcd-server-startup.sh

etcd-server-startup.sh(以192.168.116.12 主机为例)

#!/bin/sh

WORK_DIR=$(dirname $(readlink -f $0))
[ $? -eq 0 ] && cd $WORK_DIR || exit

/opt/etcd/etcd --name etcd-server-12 \
    --data-dir /data/etcd/etcd-server \
    --listen-peer-urls https://192.168.116.12:2380 \
    --listen-client-urls https://192.168.116.12:2379,http://127.0.0.1:2379 \
    --quota-backend-bytes 8000000000 \
    --initial-advertise-peer-urls https://192.168.116.12:2380 \
    --advertise-client-urls https://192.168.116.12:2379,http://127.0.0.1:2379 \
    --initial-cluster  etcd-server-12=https://192.168.116.12:2380,etcd-server-21=https://192.168.116.21:2380,etcd-server-22=https://192.168.116.22:2380 \
    --trusted-ca-file ./certs/ca.pem \
    --cert-file ./certs/etcd-peer.pem \
    --key-file ./certs/etcd-peer-key.pem \
    --client-cert-auth=true  \
    --peer-trusted-ca-file ./certs/ca.pem \
    --peer-cert-file ./certs/etcd-peer.pem \
    --peer-key-file ./certs/etcd-peer-key.pem \
    --peer-client-cert-auth=true \
    --log-outputs stdout

三台 etcd 主机中的启动脚本略有差异,需要修改的参数:name,listen-peer-urls,listen-client-urls,initial-advertise-peer-urls

修改 etcd 目录及文件的所属和权限

## /opt
chmod u+x /opt/etcd/etcd-server-startup.sh
chown -R etcd.etcd /opt/etcd/ /data/etcd /data/logs/etcd-server

supervisor 管理启动 etcd 服务

至此已经可以使用 ./etcd-server-startup.sh 启动 etcd 服务。
注意:如若直接使用 root 用户通过 ./etcd-server-startup.sh 指令启动 etcd 服务,etcd 服务会在 /data/etcd 目录下创建 root 权限的一些文件夹 etcd-server ,这样以后用 etcd 用户启动时会出现权限问题,需要该权限
因为这些进程都是要启动为后台进程,要么手动启动,要么采用后台进程管理工具,此处使用后台管理工具 supervisor 来管理 etcd 服务。

## 安装 supervisor 工具
yum install -y supervisor
## 启动 supervisor
systemctl start supervisord
## 允许 supervisor 开机启动
systemctl enable supervisord
## 向 supervisor 中增加一个启动 etcd 的配置
vi /etc/supervisord.d/etcd-server.ini

/etc/supervisord.d/etcd-server.ini 内容:

[program:etcd-server-12]
command=/opt/etcd/etcd-server-startup.sh              ; the program (relative uses PATH, can take args)
numprocs=1                                            ; number of processes copies to start (def 1)
directory=/opt/etcd                                   ; directory to cwd to before exec (def no cwd)
autostart=true                                        ; start at supervisord start (default: true)
autorestart=true                                      ; retstart at unexpected quit (default: true)
startsecs=30                                          ; number of secs prog must stay running (def. 1)
startretries=3                                        ; max # of serial start failures (default 3)
exitcodes=0,2                                         ; 'expected' exit codes for process (default 0,2)
stopsignal=QUIT                                       ; signal used to kill process (default TERM)
stopwaitsecs=10                                       ; max num secs to wait b4 SIGKILL (default 10)
user=etcd                                             ; setuid to this UNIX account to run the program
redirect_stderr=true                                  ; redirect proc stderr to stdout (default false)
stdout_logfile=/data/logs/etcd-server/etcd.stdout.log ; stdout log path, NONE for none; default AUTO
stdout_logfile_maxbytes=64MB                          ; max # logfile bytes b4 rotation (default 50MB)
stdout_logfile_backups=5                              ; # of stdout logfile backups (default 10)
stdout_capture_maxbytes=1MB                           ; number of bytes in 'capturemode' (default 0)
stdout_events_enabled=false                           ; emit events on stdout writes (default false)

更新 supervisor

supervisorctl update
### 输出 etcd-server-12: added process group

supervisor的使用命令:

## 以下命令 [servername] 换成 all 时针对 supervisor 管理的所有后台服务,(也可以使用分组)
# 启动服务命令 supervisorctl start [servername]
supervisorctl start etcd-server-12
# 停止服务命令 supervisorctl start [servername]
supervisorctl stop etcd-server-12
# 重启服务命令 supervisorctl start [servername]
supervisorctl restart etcd-server-12
# 查看指定服务状态命令 supervisorctl start [servername]
supervisorctl status etcd-server-12

相同方式启动另外两台主机的 etcd

检测 etcd :

### 在 /opt/etcd 目录下
cd /opt/etcd
## 查看各 etcd 服务是否正常
./etcdctl --cacert=./certs/ca.pem --cert=./certs/etcd-peer.pem --key=./certs/etcd-peer-key.pem --endpoints="https://192.168.116.12:2379,https://192.168.116.21:2379,https://192.168.116.22:2379" endpoint health --write-out="table"
## 查看各 etcd 服务状态
./etcdctl --cacert=./certs/ca.pem --cert=./certs/etcd-peer.pem --key=./certs/etcd-peer-key.pem --endpoints="https://192.168.116.12:2379,https://192.168.116.21:2379,https://192.168.116.22:2379" endpoint status --write-out="table"

在这里插入图片描述

使用客户端(如:etcdctl工具)连接 etcd 服务时,需要带上证书,需要验证。其他 etcd 数据操作命令可以参考 官方文件


在这里插入图片描述


k8s 主控节点

部署 kube-apiserver 集群

部署计划:在 hubo-21 和 hubo-22 上部署

下载资源:
  1. kubernetes的github页面: https://github.com/kubernetes/kubernetes
  2. 选择一个 release 版本:https://github.com/kubernetes/kubernetes/releases/tag/v1.19.11
  3. 下载已经编译好的组件包(二进制文件)地址:https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.19.md#downloads-for-v11914
  4. 下载对应的二进制文件:kubernetes-server-linux-amd64.tar.gz

下载下来放到/opt/application-src目录下:

## 在先获取, /opt/application-src 下执行
wget https://dl.k8s.io/v1.19.14/kubernetes-server-linux-amd64.tar.gz
## 解压
tar -xf kubernetes-server-linux-amd64.tar.gz
## 移动并重命名,加上版本号便于区分
mv kubernetes /opt/kubernetes-1.19.14
## 到/opt 目录 创建软连接
cd /opt/
ln -s /opt/kubernetes /opt/kubernetes-1.19.14

删除一些没有用的资源

## 到 /opt/kubernetes 目录下 删除源码包 kubernetes-src.tar.gz
cd /opt/kubernetes
rm -f kubernetes-src.tar.gz
## 到 /opt/kubernetes/server/bin 路径下删除不需要的 docker 镜像文件
cd /opt/kubernetes/server/bin
rm -f *.tar *_tag
签发证书

hubo-200 主机制作证书,并下发。所以在 hubo-200 的 /opt/certs 目录下完成。

客户端与服务端通信时需要的证书:client 证书

例如 apiserver 与 etcd 服务通信时,需要携带 client 证书

客户端证书配置文件:client-csr.json

## hubo-200 主机 /opt/certs/ 目录下
vi /opt/certs/client-csr.json
{
    "CN": "k8s-node",
    "hosts": [
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "ST": "liaoning",
            "L": "shenyang",
            "O": "edu",
            "OU": "development"
        }
    ]
}

制作证书:

## /opt/certs 目录下
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client client-csr.json | cfssl-json -bare client

在这里插入图片描述

服务端与客户端通信时需要的证书:server 证书

例如 apiserver 和其它 k8s 组件通信使用

编辑配置文件:

vi /opt/certs/apiserver-csr.json
{
    "CN": "k8s-apiserver",
    "hosts": [
        "127.0.0.1",
        "192.168.0.1",
        "kubernetes.default",
        "kubernetes.default.svc",
        "kubernetes.default.svc.cluster",
        "kubernetes.default.svc.cluster.local",
        "192.168.116.10",
        "192.168.116.21",
        "192.168.116.22",
        "192.168.116.23"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "ST": "liaoning",
            "L": "shenyang",
            "O": "edu",
            "OU": "development"
        }
    ]
}

签发证书

## /opt/certs 目录下
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server apiserver-csr.json | cfssl-json -bare apiserver

在这里插入图片描述

证书下发到 hubo-21 和 hubo-22
for i in 21 22;do echo hubo-$i;ssh hubo-$i "mkdir /opt/kubernetes/server/bin/certs";scp apiserver-key.pem apiserver.pem ca-key.pem ca.pem client-key.pem client.pem hubo-$i:/opt/kubernetes/server/bin/certs/;done

在这里插入图片描述

配置 apiserver 日志审计

涉及此配置的主机: hubo-21 、hubo-22

mkdir /opt/kubernetes/conf
vi /opt/kubernetes/conf/audit.yaml
apiVersion: audit.k8s.io/v1beta1 # This is required.
kind: Policy
# Don't generate audit events for all requests in RequestReceived stage.
omitStages:
  - "RequestReceived"
rules:
  # Log pod changes at RequestResponse level
  - level: RequestResponse
    resources:
    - group: ""
      # Resource "pods" doesn't match requests to any subresource of pods,
      # which is consistent with the RBAC policy.
      resources: ["pods"]
  # Log "pods/log", "pods/status" at Metadata level
  - level: Metadata
    resources:
    - group: ""
      resources: ["pods/log", "pods/status"]

  # Don't log requests to a configmap called "controller-leader"
  - level: None
    resources:
    - group: ""
      resources: ["configmaps"]
      resourceNames: ["controller-leader"]

  # Don't log watch requests by the "system:kube-proxy" on endpoints or services
  - level: None
    users: ["system:kube-proxy"]
    verbs: ["watch"]
    resources:
    - group: "" # core API group
      resources: ["endpoints", "services"]

  # Don't log authenticated requests to certain non-resource URL paths.
  - level: None
    userGroups: ["system:authenticated"]
    nonResourceURLs:
    - "/api*" # Wildcard matching.
    - "/version"

  # Log the request body of configmap changes in kube-system.
  - level: Request
    resources:
    - group: "" # core API group
      resources: ["configmaps"]
    # This rule only applies to resources in the "kube-system" namespace.
    # The empty string "" can be used to select non-namespaced resources.
    namespaces: ["kube-system"]

  # Log configmap and secret changes in all other namespaces at the Metadata level.
  - level: Metadata
    resources:
    - group: "" # core API group
      resources: ["secrets", "configmaps"]

  # Log all other resources in core and extensions at the Request level.
  - level: Request
    resources:
    - group: "" # core API group
    - group: "extensions" # Version of group should NOT be included.

  # A catch-all rule to log all other requests at the Metadata level.
  - level: Metadata
    # Long-running requests like watches that fall under this rule will not
    # generate an audit event in RequestReceived.
    omitStages:
      - "RequestReceived"
配置启动脚本

涉及此配置的主机: hubo-21 、hubo-22

vi /opt/kubernetes/server/bin/kube-apiserver-startup.sh

#!/bin/bash

WORK_DIR=$(dirname $(readlink -f $0))
[ $? -eq 0 ] && cd $WORK_DIR || exit

/opt/kubernetes/server/bin/kube-apiserver \
    --apiserver-count 2 \
    --audit-log-path /data/logs/kubernetes/kube-apiserver/audit-log \
    --audit-policy-file ../../conf/audit.yaml \
    --authorization-mode RBAC \
    --client-ca-file ./certs/ca.pem \
    --requestheader-client-ca-file ./certs/ca.pem \
    --enable-admission-plugins NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota \
    --etcd-cafile ./certs/ca.pem \
    --etcd-certfile ./certs/client.pem \
    --etcd-keyfile ./certs/client-key.pem \
    --etcd-servers https://192.168.116.12:2379,https://192.168.116.21:2379,https://192.168.116.22:2379 \
    --service-account-key-file ./certs/ca-key.pem \
    --service-cluster-ip-range 192.100.0.0/16 \
    --service-node-port-range 3000-29999 \
    --target-ram-mb=1024 \
    --kubelet-client-certificate ./certs/client.pem \
    --kubelet-client-key ./certs/client-key.pem \
    --log-dir  /data/logs/kubernetes/kube-apiserver \
    --tls-cert-file ./certs/apiserver.pem \
    --tls-private-key-file ./certs/apiserver-key.pem \
    --v 2

这里需要修改 --etcd-servers https://192.168.116.12:2379,https://192.168.116.21:2379,https://192.168.116.22:2379 分别三台etcd的地址

添加可执行权限:
chmod +x /opt/kubernetes/server/bin/kube-apiserver-startup.sh

supervisor 管理 apiserver

涉及此配置的主机: hubo-21 、hubo-22

添加 supervisor 启动配置:

vi /etc/supervisord.d/kube-apiserver.ini

[program:kube-apiserver-21]
command=/opt/kubernetes/server/bin/kube-apiserver-startup.sh
numprocs=1
directory=/opt/kubernetes/server/bin
autostart=true
autorestart=true
startsecs=30
startretries=3
exitcodes=0,2
stopsignal=QUIT
stopwaitsecs=10
user=root
redirect_stderr=true
stdout_logfile=/data/logs/kubernetes/kube-apiserver/apiserver.stdout.log
stdout_logfile_maxbytes=64MB
stdout_logfile_backups=5
stdout_capture_maxbytes=1MB
stdout_events_enabled=false

program:kube-apiserver-21 须有根据不同的主机设置

创建需要的目录:

mkdir -p /data/logs/kubernetes/kube-apiserver/

更新 supervisor 的配置,查看状态

supervisorctl state
supervisorctl status

在这里插入图片描述

启动停止命令:

supervisorctl start kube-apiserver-21
supervisorctl stop kube-apiserver-21
supervisorctl restart kube-apiserver-21
supervisorctl status kube-apiserver-21

通过进程查看启动状态:

netstat -lntp|grep api

ps uax|grep kube-apiserver|grep -v grep

在这里插入图片描述

apiserver L4代理

在 hubo-11 和 hubo-12 主机为 apiserver 做代理

源码编译安装:

## 安装必要的编译环境
yum -y install gcc gcc-c++ make automake autoconf pcre pcre-devel zlib zlib-devel openssl openssl-devel libtool
## /opt/application-src 目录下
wget http://nginx.org/download/nginx-1.20.1.tar.gz
tar -xf nginx-1.20.1.tar.gz
mv nginx-1.20.1 /opt/nginx-1.20.1
cd /opt
ln -s nginx-1.20.1 nginx
cd nginx
### 配置编译目标文件(根据个人需求可对配置命令做出修改) 具体选型可以 ./configure --help 查看
./configure  --prefix=/usr/local/nginx  --sbin-path=/usr/local/nginx/sbin/nginx --conf-path=/usr/local/nginx/conf/nginx.conf --error-log-path=/var/log/nginx/error.log  --http-log-path=/var/log/nginx/access.log  --pid-path=/var/run/nginx.pid --lock-path=/var/lock/nginx.lock  --user=nginx --group=nginx --with-http_ssl_module --with-http_stub_status_module --with-http_gzip_static_module --http-client-body-temp-path=/var/tmp/nginx/client/ --http-proxy-temp-path=/var/tmp/nginx/proxy/ --http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi --http-scgi-temp-path=/var/tmp/nginx/scgi  --with-stream --with-pcre

## 创建需要的目录
mkdir -p /var/tmp/nginx/client/
## 防止启动时保持 nginx: [emerg] open() "/var/run/nginx/nginx.pid" failed (2: No such file or directory)
mkdir /var/run/nginx

## 安装
make && make install

## 检测配置
/usr/local/nginx/sbin/nginx -t

## 修改配置
vi /usr/local/nginx/conf/nginx.conf

## 不属于 http 块,在文件最后追加
stream {
    log_format proxy '$time_local|$remote_addr|$upstream_addr|$protocol|$status|'
                     '$session_time|$upstream_connect_time|$bytes_sent|$bytes_received|'
                     '$upstream_bytes_sent|$upstream_bytes_received' ;

    upstream kube-apiserver {
        server 192.168.116.21:6443     max_fails=3 fail_timeout=30s;
        server 192.168.116.22:6443     max_fails=3 fail_timeout=30s;
    }
    server {
        listen 7443;
        proxy_connect_timeout 2s;
        proxy_timeout 900s;
        proxy_pass kube-apiserver;
        access_log /var/log/nginx/proxy.log proxy;
    }
}

启动 Nginx 服务:

## 启动
/usr/local/nginx/sbin/nginx  -c   /usr/local/nginx/conf/nginx.conf
/usr/local/nginx/sbin/nginx -s stop   #停止Nginx
/usr/local/nginx/sbin/nginx -s reload    #不停止服务,重新加载配置文件

测试:
ps aux|grep nginx
curl 127.0.0.1:7443
cat /var/log/nginx/proxy.log
在这里插入图片描述

keepalive 安装部署—实现 vip :192.168.116.10
yum install keepalived -y
vi /etc/keepalived/check_port.sh
#!/bin/bash

CHK_PORT=$1
if [ -n "$CHK_PORT" ];then
        PORT_PROCESS=`ss -lnt|grep $CHK_PORT|wc -l`
        if [ $PORT_PROCESS -eq 0 ];then
                echo "Port $CHK_PORT Is Not Used,End."
                exit 1
        fi
else
        echo "Check Port Can Not Be Empty!"
fi

配置主备 keepalived :

hubo-11 这只为主节点:配置如下:
[root@hubo-11 ~]# vi /etc/keepalived/keepalived.conf

! Configuration File for keepalived

global_defs {
   router_id 192.168.116.11
}

vrrp_script chk_nginx {
    script "/etc/keepalived/check_port.sh 7443"
    interval 2
    weight -20
}

vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 50
    mcast_src_ip 192.168.116.11
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    track_script {
        chk_nginx
    }
    virtual_ipaddress {
        192.168.116.10/24 label ens33:0
    }
}

hubo-12 设置为备用:配置如下
[root@hubo-12 ~]# vi /etc/keepalived/keepalived.conf

! Configuration File for keepalived

global_defs {
   router_id 192.168.116.12
}

vrrp_script chk_nginx {
    script "/etc/keepalived/check_port.sh 7443"
    interval 2
    weight -20
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 50
    mcast_src_ip 192.168.116.12
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    track_script {
        chk_nginx
    }
    virtual_ipaddress {
        192.168.116.10/24
    }
}

启动keepalived 并设置开机启动,测试方式很简单,查看 ip addr 主节点上会有 vip 192.168.116.10,如果主节点宕机,vip 会出现在备用节点。
curl 192.168.116.10:7443 也可以在对应的 nginx 日志中看到访问记录。

状态查看:systemctl status keepalived
在这里插入图片描述

keepalive 详细内容参考: 参考1参考2

controller-manager 安装

部署计划:在 hubo-21 和 hubo-22 上部署

controller-manager 设置为只调用当前主机的 apiserver 服务,走 127.0.0.1 ,因此不配制SSL证书。

创建启动脚本

vi /opt/kubernetes/server/bin/kube-controller-manager-startup.sh

#!/bin/sh
WORK_DIR=$(dirname $(readlink -f $0))
[ $? -eq 0 ] && cd $WORK_DIR || exit

/opt/kubernetes/server/bin/kube-controller-manager \
    --cluster-cidr=172.7.0.0/16 \
    --leader-elect=true \
    --log-dir=/data/logs/kubernetes/kube-controller-manager \
    --master=http://127.0.0.1:8080 \
    --service-account-private-key-file=./certs/ca-key.pem \
    --service-cluster-ip-range=192.100.0.0/16 \
    --root-ca-file=./certs/ca.pem \
    --v=2

常规操作,添加可执行权限:chmod u+x /opt/kubernetes/server/bin/kube-controller-manager-startup.sh

配置supervisor启动配置

vi /etc/supervisord.d/kube-controller-manager.ini

[program:kube-controller-manager-21]
command=/opt/kubernetes/server/bin/kube-controller-manager-startup.sh             ; the program (relative uses PATH, can take args)
numprocs=1                                                                        ; number of processes copies to start (def 1)
directory=/opt/kubernetes/server/bin                                              ; directory to cwd to before exec (def no cwd)
autostart=true                                                                    ; start at supervisord start (default: true)
autorestart=true                                                                  ; retstart at unexpected quit (default: true)
startsecs=30                                                                      ; number of secs prog must stay running (def. 1)
startretries=3                                                                    ; max # of serial start failures (default 3)
exitcodes=0,2                                                                     ; 'expected' exit codes for process (default 0,2)
stopsignal=QUIT                                                                   ; signal used to kill process (default TERM)
stopwaitsecs=10                                                                   ; max num secs to wait b4 SIGKILL (default 10)
user=root                                                                         ; setuid to this UNIX account to run the program
redirect_stderr=true                                                              ; redirect proc stderr to stdout (default false)
stdout_logfile=/data/logs/kubernetes/kube-controller-manager/controller.stdout.log  ; stderr log path, NONE for none; default AUTO
stdout_logfile_maxbytes=64MB                                                      ; max # logfile bytes b4 rotation (default 50MB)
stdout_logfile_backups=4                                                          ; # of stdout logfile backups (default 10)
stdout_capture_maxbytes=1MB                                                       ; number of bytes in 'capturemode' (default 0)
stdout_events_enabled=false                                                       ; emit events on stdout writes (default false)
## 创建日志目录
mkdir -p /data/logs/kubernetes/kube-controller-manager/
启动
## supervisor 更新配置
supervisorctl update
## 查看状态
supervisorctl status

kube-scheduler 调度服务安装

部署计划:在 hubo-21 和 hubo-22 上部署

kube-scheduler 设置为只调用当前机器的 apiserver,走127.0.0.1网卡,因此不配制SSL证书

创建启动脚本

vi /opt/kubernetes/server/bin/kube-scheduler-startup.sh

#!/bin/sh
WORK_DIR=$(dirname $(readlink -f $0))
[ $? -eq 0 ] && cd $WORK_DIR || exit

/opt/kubernetes/server/bin/kube-scheduler \
    --leader-elect  \
    --log-dir /data/logs/kubernetes/kube-scheduler \
    --master http://127.0.0.1:8080 \
    --v 2
## 添加可执行权限
chmod u+x /opt/kubernetes/server/bin/kube-scheduler-startup.sh
## 创建调度日志目录
mkdir -p /data/logs/kubernetes/kube-scheduler
配置supervisor启动配置

vi /etc/supervisord.d/kube-scheduler.ini

[program:kube-scheduler-21]
command=/opt/kubernetes/server/bin/kube-scheduler-startup.sh                     
numprocs=1                                                               
directory=/opt/kubernetes/server/bin                                     
autostart=true                                                           
autorestart=true                                                         
startsecs=30                                                             
startretries=3                                                           
exitcodes=0,2                                                            
stopsignal=QUIT                                                          
stopwaitsecs=10                                                          
user=root                                                                
redirect_stderr=true                                                     
stdout_logfile=/data/logs/kubernetes/kube-scheduler/scheduler.stdout.log 
stdout_logfile_maxbytes=64MB                                             
stdout_logfile_backups=4                                                 
stdout_capture_maxbytes=1MB                                              
stdout_events_enabled=false 
启动
supervisorctl update

supervisorctl status 

检查主控节点状态

## 创建一个软连接导 /usr/local/bin/  方便使用命令
ln -s /opt/kubernetes/server/bin/kubectl /usr/local/bin/
kubectl get cs

k8s 运算节点

主控节点和运算节点何以在同一台机器上,逻辑上把他们看成分开的,所以这里将运算节点也部署在 hubo-21 和 hubo-22 上。

kubelet 部署

签发证书

配置:

由 hubo-200 主机签发 kubelet 服务使用的证书

## 在 hubo-200 主机
cd /opt/certs/

证书配置 json 文件:kubelet-csr.json

{
    "CN": "k8s-kubelet",
    "hosts": [
    "127.0.0.1",
    "192.168.116.10",
    "192.168.116.21",
    "192.168.116.22",
    "192.168.116.23",
    "192.168.116.24",
    "192.168.116.25",
    "192.168.116.26",
    "192.168.116.27",
    "192.168.116.28"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "ST": "liaoning",
            "L": "shenyang",
            "O": "edu",
            "OU": "development"
        }
    ]
}

hosts 中填写所有可能的 kubelet 机器IP。

签发:

## /opt/certs/ 目录下制作证书
cfssl gencert -ca=ca.pem -ca-key ca-key.pem -config=ca-config.json -profile=server kubelet-csr.json | cfssl-json  -bare kubelet
## 查看
ls kubelet* -l
## 分发
scp kubelet.pem kubelet-key.pem hubo-21:/opt/kubernetes/server/bin/certs/
scp kubelet.pem kubelet-key.pem hubo-22:/opt/kubernetes/server/bin/certs/

在这里插入图片描述

创建 kubelet 配置

在 hubo-21 和 hubo-22 主机上操作,在 /opt/kubernetes/conf/ 目录下创建配置

  1. set-cluster
    Sets a cluster entry in kubeconfig

    kubectl config set-cluster myk8s \
    --certificate-authority=/opt/kubernetes/server/bin/certs/ca.pem \
    --embed-certs=true \
    --server=https://192.168.116.10:7443 \
    --kubeconfig=/opt/kubernetes/conf/kubelet.kubeconfig
    

    myk8s 是给集群起的一个名称
    server 参数指向的是 apiserver,但是为了高可用做了代理,并且使用了 vip ,所有指向了192.168.116.10:7443
    kubeconfig 表示配置文件的位置,将生成 /opt/kubernetes/conf/kubelet.kubeconfig 文件
    embed-certs 表示是否下给你配置文件中嵌入证书,true 时会把正式通过base64编码后写道配置文件中

    命令的详细信息可以使用 -h 产看:kubectl config set-cluster -h

  2. set-credentials
    Sets a user entry in kubeconfig

    kubectl config set-credentials k8s-node \
    --client-certificate=/opt/kubernetes/server/bin/certs/client.pem \
    --client-key=/opt/kubernetes/server/bin/certs/client-key.pem \
    --embed-certs=true \
    --kubeconfig=/opt/kubernetes/conf/kubelet.kubeconfig
    
  3. set-context
    Sets a context entry in kubeconfig

    kubectl config set-context myk8s-context \
    --cluster=myk8s \
    --user=k8s-node \
    --kubeconfig=/opt/kubernetes/conf/kubelet.kubeconfig
    

    这里 user=k8s-node 是用户名,这个会对应到 client 证书中设置的 CN 值。也就是说,之前创建的 client 证书在 k8s 集群中只能给用户名为 user=k8s-node 的用户使用。

  4. use-context
    Sets the current-context in a kubeconfig file

    kubectl config use-context myk8s-context --kubeconfig=/opt/kubernetes/conf/kubelet.kubeconfig
    

在 hubo-21 主机上指向完成以上四个步骤后,会在 /opt/kubernetes/conf/ 目录下生成一个 kubelet 的配置文件 kubelet.kubeconfig,其中存储了以上四个步骤的配置,把改文件传到 hubo-22 主机上对应的位置即可,不需要在 hubo-22 上再重发这个步骤。

## 在 hubo-21 上执行
scp /opt/kubernetes/conf/kubelet.kubeconfig hubo-22:/opt/kubernetes/conf/
角色绑定(ClusterRoleBinding —— 是一个集群资源,被存储到了 etcd 中)

授权 k8s-node 用户,在配置 kubelet 时设置了一个k8s集群用户 k8s-node,现在需要授予它一个集群权限,这个权限使它在集群中具备成为运算节点的权限。【RBAC】

创建配置文件:vi /opt/kubernetes/conf/k8s-node.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: k8s-node
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:node
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: k8s-node
### 创建
kubectl create -f k8s-node.yaml
### 查看
kubectl get clusterrolebinding k8s-node
kubectl get clusterrolebinding k8s-node -o yaml

CSDN

这个集群用户角色在 hubo-21 上创建即可,创建成功后,在 hubo-22 也可以查到。
删除指令 kubectl delete -f k8s-node.yaml

装备 pause 基础镜像

在hubo-200 主机上操作,从共有镜像仓库拉取 pause 镜像(或者上传镜像文件,docker load 加载到 hubo-200 主机的docker 环境中),然后上传到私有仓库。
pause 基础镜像与 Pod 一一对应的,在初始话 Pod 时又它来完成一些共享资源的定义,然后 Pod 中的其他资源都会共享这些资源(如网络资源)。【详细参考1详细参考2

## hubo-200 上执行
docker pull kubernetes/pause
docker tag kubernetes/pause:latest harbor.k8s.com/public/pause:latest
docker push harbor.k8s.com/public/pause:latest

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

关于 docker 的基础操作参考连接: docker 学习笔记专栏
如果传不上去检查是否登录,如果没有:docker login -u admin harbor.k8s.com 详细内容在本文 harbor 仓库搭建章节又介绍。

创建启动参数配置文件和启动脚本

在 hubo-21 、 hubo-22 (即前期设计的 node 节点)创建脚本。

启动参数配置文件

官网参考文档 KubeletConfiguration.yml

vi /opt/kubernetes/conf/kubelet-configuration.yaml

apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd
clusterDNS:
- 192.100.0.2
clusterDomain: cluster.local
#cgroupRoot: /systemd/system.slice
kubeletCgroups: /systemd/system.slice
failSwapOn: false
authentication:
  x509:
    clientCAFile: /opt/kubernetes/server/bin/certs/ca.pem
  anonymous:
    enabled: false
tlsCertFile: /opt/kubernetes/server/bin/certs/kubelet.pem
tlsPrivateKeyFile: /opt/kubernetes/server/bin/certs/kubelet-key.pem
imageGCHighThresholdPercent: 80
imageGCLowThresholdPercent: 20

踩坑:老版本中这些参数都可以在启动命令中指定,但是在较新的版本中有些参数必须在这个配置文件中指定,然后再启动时通过 --config [file-path] 来指定参数配置文件
详细内容:官网:Kubelet Configuration (v1beta1)

启动脚本
vi /opt/kubernetes/server/bin/kubelet-startup.sh

#!/bin/sh

WORK_DIR=$(dirname $(readlink -f $0))
[ $? -eq 0 ] && cd $WORK_DIR || exit

/opt/kubernetes/server/bin/kubelet \
    --config /opt/kubernetes/conf/kubelet-configuration.yaml \
    --runtime-cgroups=/systemd/system.slice \
    --hostname-override hubo-21.host.com \
    --kubeconfig ../../conf/kubelet.kubeconfig \
    --log-dir /data/logs/kubernetes/kube-kubelet \
    --pod-infra-container-image harbor.k8s.com/public/pause:latest \
    --root-dir /data/kubelet
chmod u+x /opt/kubernetes/server/bin/kubelet-startup.sh
mkdir -p /data/logs/kubernetes/kube-kubelet /data/kubelet

启动时踩的坑:【misconfiguration : kubelet cgroup driver: “systemd” is different from docker cgroup driver: "cgro】- - - - 分析原因:这是由于 docker cgroup driver 和kubelet cgroup driver 配置不一致导致
解决办法:修改 docker 的 daemon.json 文件
在这里插入图片描述
重启:systemctl restart docker

交给 supervisor 管理

vi /etc/supervisord.d/kube-kubelet.ini

[program:kube-kubelet-21]
command=/opt/kubernetes/server/bin/kubelet-startup.sh
numprocs=1
directory=/opt/kubernetes/server/bin
autostart=true
autorestart=true
startsecs=30
startretries=3
exitcodes=0,2
stopsignal=QUIT
stopwaitsecs=10
user=root
redirect_stderr=true
stdout_logfile=/data/logs/kubernetes/kube-kubelet/kubelet.stdout.log
stdout_logfile_maxbytes=64MB
stdout_logfile_backups=5
stdout_capture_maxbytes=1MB
stdout_events_enabled=false
supervisorctl update
supervisorctl status
## 查看集群中的节点资源
kubectl get node

在这里插入图片描述
给节点添加角色标记:

## 加 node 标签
kubectl label node hubo-21.host.com node-role.kubernetes.io/node=
kubectl label node hubo-22.host.com node-role.kubernetes.io/node=
## 加 master标签
kubectl label node hubo-21.host.com node-role.kubernetes.io/master=
kubectl label node hubo-22.host.com node-role.kubernetes.io/master=

kubectl get node
## 标记后的结果(这个只是标记作用,应用:例如污点处理)
NAME               STATUS   ROLES         AGE     VERSION
hubo-21.host.com   Ready    master,node   31m     v1.19.14
hubo-22.host.com   Ready    master,node   5m40s   v1.19.14

kube-proxy部署

签发证书

由 hubo-200 主机签发 kube-proxy服务使用的证书

配置:
vi /opt/certs/kube-proxy-csr.json

{
    "CN": "system:kube-proxy",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "ST": "liaoning",
            "L": "shenyang",
            "O": "edu",
            "OU": "development"
        }
    ]
}

CN可以对应 k8s 集群中的角色,这里设置为 system:kube-proxy 对应的就是集群中的 system:kube-proxy 角色。
在上一节(kubelet 部署)中通过 kubectl create -f k8s-node.yaml 创建了一个角色绑定资源,创建的角色是 system:node,并绑定了 k8s-node 用户。
在之前创建 client 证书时,使用的 CN 是 k8s-node ,意思是对应集群中的 k8s-node 用户,也就是说,这个证书在 k8s 集群中只能给 k8s-node 用户使用。所以 kube-proxy 用户(该用户在后面的配置中设置)需要额外定制自己的证书。【当然,kube-proxy 也可以叫 k8s-node,者应就可以用一套client证书了】

签发证书

## /opt/certs/ 目录下执行
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client kube-proxy-csr.json |cfssl-json -bare kube-proxy-client

## 查看
ls kube-proxy-c* -l

分发证书

## /opt/certs/ 目录下执行
scp kube-proxy-client-key.pem kube-proxy-client.pem hubo-21:/opt/kubernetes/server/bin/certs/
scp kube-proxy-client-key.pem kube-proxy-client.pem hubo-22:/opt/kubernetes/server/bin/certs/

执行结果:

[root@hubo-200 certs]# scp kube-proxy-client-key.pem kube-proxy-client.pem hubo-21:/opt/kubernetes/server/bin/certs/
kube-proxy-client-key.pem                                                     100% 1679     1.7MB/s   00:00    
kube-proxy-client.pem                                                         100% 1403   776.0KB/s   00:00    
[root@hubo-200 certs]# scp kube-proxy-client-key.pem kube-proxy-client.pem hubo-22:/opt/kubernetes/server/bin/certs/
kube-proxy-client-key.pem                                                     100% 1679     1.4MB/s   00:00    
kube-proxy-client.pem                                                         100% 1403   845.2KB/s   00:00    

创建 kube-proxy 配置

同 kubelet 创建配置类似(过程相同,内容有细微区别),在 hubo-21 上完成,然后把生成的文件复制到 hubo-22上即可。
/opt/kubernetes/conf/ 目录下操作

  1. set-cluster

    kubectl config set-cluster myk8s \
    --certificate-authority=/opt/kubernetes/server/bin/certs/ca.pem \
    --embed-certs=true \
    --server=https://192.168.116.10:7443 \
    --kubeconfig=/opt/kubernetes/conf/kube-proxy.kubeconfig
    
  2. set-credentials

    kubectl config set-credentials kube-proxy \
    --client-certificate=/opt/kubernetes/server/bin/certs/kube-proxy-client.pem \
    --client-key=/opt/kubernetes/server/bin/certs/kube-proxy-client-key.pem \
    --embed-certs=true \
    --kubeconfig=/opt/kubernetes/conf/kube-proxy.kubeconfig
    

    创建一个 kube-proxy 用户记录。

  3. set-context
    Sets a context entry in kubeconfig

    kubectl config set-context myk8s-context \
    --cluster=myk8s \
    --user=kube-proxy \
    --kubeconfig=/opt/kubernetes/conf/kube-proxy.kubeconfig
    

    这里 user=kube-proxy 是选用的用户.

  4. use-context
    Sets the current-context in a kubeconfig file

    kubectl config use-context myk8s-context --kubeconfig=/opt/kubernetes/conf/kube-proxy.kubeconfig
    

将 kube-proxy.kubeconfig 配置文件同步到 hubo-22 主机:

## 在 hubo-21 上执行
scp /opt/kubernetes/conf/kube-proxy.kubeconfig hubo-22:/opt/kubernetes/conf/
加载ipvs模块

三种流量调度模式(代理模式): namespace,iptables,ipvs
详细参考【kube-proxy的三种代理模式】

## 加载 ipvs 模块
for i in $(ls /usr/lib/modules/$(uname -r)/kernel/net/netfilter/ipvs|grep -o "^[^.]*");do echo $i; /sbin/modinfo -F filename $i >/dev/null 2>&1 && /sbin/modprobe $i;done

## 查看ipvs模块
lsmod | grep ip_vs  
创建启动脚本

启动参数配置文件

官网参考文档 KubeProxyConfiguration.yml

官网参考文档 KubeProxyConfiguration.yml 中的数据多了一层,KubeProxyConfiguration:,添加了这个启动会失败,层次不对,导致读不到响应的配置参数。
参数配置文件以 hubo-21 为例,hubo-22上需要改一下 --hostnameOverride 的值。

vi /opt/kubernetes/conf/kube-proxy-configuration.yaml

apiVersion: kubeproxy.config.k8s.io/v1alpha1
clientConnection:
  kubeconfig: /opt/kubernetes/conf/kube-proxy.kubeconfig
clusterCIDR: "172.7.0.0/16"
hostnameOverride: "hubo-21.host.com"
ipvs:
  scheduler: "nq"
kind: KubeProxyConfiguration
mode: "ipvs"

参数详细说明:官网:kube-proxy Configuration (v1alpha1)

启动脚本

vi /opt/kubernetes/server/bin/kube-proxy-startup.sh

#!/bin/sh

WORK_DIR=$(dirname $(readlink -f $0))
[ $? -eq 0 ] && cd $WORK_DIR || exit

/opt/kubernetes/server/bin/kube-proxy --config /opt/kubernetes/conf/kube-proxy-configuration.yaml

授与可执行权限:
chmod u+x /opt/kubernetes/server/bin/kube-proxy-startup.sh

创建用到的目录:
mkdir -p /data/logs/kubernetes/kube-proxy

交给 supervisor 管理

以 hubo-21 为例,hubo-22上需要改一下 program 名称

vi /etc/supervisord.d/kube-proxy.ini

[program:kube-proxy-21]
command=/opt/kubernetes/server/bin/kube-proxy-startup.sh                
numprocs=1                                                      
directory=/opt/kubernetes/server/bin                            
autostart=true                                                  
autorestart=true                                                
startsecs=30                                                    
startretries=3                                                  
exitcodes=0,2                                                   
stopsignal=QUIT                                                 
stopwaitsecs=10                                                 
user=root                                                       
redirect_stderr=true                                            
stdout_logfile=/data/logs/kubernetes/kube-proxy/proxy.stdout.log
stdout_logfile_maxbytes=64MB                                    
stdout_logfile_backups=5                                       
stdout_capture_maxbytes=1MB                                     
stdout_events_enabled=false
## 更新 supervisor 配置
supervisorctl update
## 检查是否启动成功
supervisorctl status

查看结果:所有组件均已启动

[root@hubo-21 bin]# supervisorctl status
etcd-server-21                   RUNNING   pid 1102, uptime 3:00:30
kube-apiserver-21                RUNNING   pid 1080, uptime 3:00:30
kube-controller-manager-21       RUNNING   pid 1800, uptime 2:57:32
kube-kubelet-21                  RUNNING   pid 1087, uptime 3:00:30
kube-proxy-21                    RUNNING   pid 2659, uptime 0:00:47
kube-scheduler-21                RUNNING   pid 1791, uptime 2:57:32

说明:这里主控节点的组件和运算节点的组件都部署在了同一台机器上,主控节点和运算节点可以分开部署,原理是一样的。同意,如果主控节点不要求高可用,也可以之部署一台主控节点,其他的运算节点都与它交互。

验证集群

利用 ipvsadm 查看集群网络结构
yum install -y ipvsadm
ipvsadm -Ln
[root@hubo-21 bin]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.0.1:443 nq
  -> 192.168.116.21:6443          Masq    1      0          0         
  -> 192.168.116.22:6443          Masq    1      0          0 
[root@hubo-22 bin]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.0.1:443 nq
  -> 192.168.116.21:6443          Masq    1      0          0         
  -> 192.168.116.22:6443          Masq    1      0          0 
创建 pod 资源
Pod 资源配置文件

官方参考文档 demo-pod.yml

## 把一些业务资源的配置文件放到 /opt/kubernetes/conf/resource/ 里面,方便查找
mkdir /opt/kubernetes/conf/resource
cd /opt/kubernetes/conf/resource/
## 创建一个 nginx 的 pod 资源配置文件
vi nginx-ds.yml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-ds
  labels:
    app: nginx-ds
spec:
  containers:
    - name: my-nginx
      image: harbor.k8s.com/public/nginx:v1.7.9
      ports:
        - containerPort: 80
          name: "http-server"
通过刚才的配置文件创建资源
## 在 /opt/kubernetes/conf/resource/ 目录下执行
kubectl create -f nginx-ds.yml

结果:

[root@hubo-22 resource]# kubectl create -f nginx-ds.yml 
pod/nginx-ds created

查看集群中的 pod 资源(在另一台机器上查看,检查集群是否正确运行)

## 在 hubo-21 执行
kubectl get pods

结果:

[root@hubo-21 bin]# kubectl get pods
NAME       READY   STATUS              RESTARTS   AGE
nginx-ds   0/1     ContainerCreating   0          26s
[root@hubo-21 ~]# kubectl get pods
NAME       READY   STATUS    RESTARTS   AGE
nginx-ds   1/1     Running   0          3m33s
[root@hubo-21 ~]# 

## 查看 pods 信息
kubectl get pods -owide
[root@hubo-21 ~]# kubectl get pods -owide
NAME       READY   STATUS    RESTARTS   AGE     IP           NODE               NOMINATED NODE   READINESS GATES
nginx-ds   1/1     Running   0          5m13s   172.7.21.2   hubo-21.host.com   <none>           <none>

可以看出,这个 pod 被放到了 hubo-21 宿主机(虽然是在hubo-22上创建的资源)。此时测试是否可以访问,因为这是一个 pod 资源,还没有接 service 资源,现在只能内部访问,在 hubo-21 上 curl 一下:

[root@hubo-21 ~]# curl 172.7.21.2
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

但是在 hubo-22 上curl 这个地址会超时,因为此时他们直接的完了还没有通,需要借助 flannel 完成 Pod 网络的互联。


在这里插入图片描述


Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐