無限風域

CentOS7部署Kubernetes 1.10.2

[RUBYTOC]

[准备]^(Prepare)

  准备docker和Kubernetes的国内镜像源, 把源文件加入到/etc/yum.repo.d/即可。
  源采用中科大的docker源和阿里的Kubernetes源, 若能访问"外网"请自行更换baseurl.
  如果可访问"外网"即可不用关心, 如果使用代理联网可参考[配置]^(Config)章节进行proxy设置。

Docker Repository

[docker-ce-stable]
name=Docker CE Stable - $basearch
baseurl=http://mirrors.ustc.edu.cn/docker-ce/linux/centos/7/$basearch/stable
enabled=1
gpgcheck=1
gpgkey=http://mirrors.ustc.edu.cn/docker-ce/linux/centos/gpg

[docker-ce-stable-debuginfo]
name=Docker CE Stable - Debuginfo $basearch
baseurl=http://mirrors.ustc.edu.cn/docker-ce/linux/centos/7/debug-$basearch/stable
enabled=0
gpgcheck=1
gpgkey=http://mirrors.ustc.edu.cn/docker-ce/linux/centos/gpg

[docker-ce-stable-source]
name=Docker CE Stable - Sources
baseurl=http://mirrors.ustc.edu.cn/docker-ce/linux/centos/7/source/stable
enabled=0
gpgcheck=1
gpgkey=http://mirrors.ustc.edu.cn/docker-ce/linux/centos/gpg

[docker-ce-edge]
name=Docker CE Edge - $basearch
baseurl=http://mirrors.ustc.edu.cn/docker-ce/linux/centos/7/$basearch/edge
enabled=0
gpgcheck=1
gpgkey=http://mirrors.ustc.edu.cn/docker-ce/linux/centos/gpg

[docker-ce-edge-debuginfo]
name=Docker CE Edge - Debuginfo $basearch
baseurl=http://mirrors.ustc.edu.cn/docker-ce/linux/centos/7/debug-$basearch/edge
enabled=0
gpgcheck=1
gpgkey=http://mirrors.ustc.edu.cn/docker-ce/linux/centos/gpg

[docker-ce-edge-source]
name=Docker CE Edge - Sources
baseurl=http://mirrors.ustc.edu.cn/docker-ce/linux/centos/7/source/edge
enabled=0
gpgcheck=1
gpgkey=http://mirrors.ustc.edu.cn/docker-ce/linux/centos/gpg

[docker-ce-test]
name=Docker CE Test - $basearch
baseurl=http://mirrors.ustc.edu.cn/docker-ce/linux/centos/7/$basearch/test
enabled=0
gpgcheck=1
gpgkey=http://mirrors.ustc.edu.cn/docker-ce/linux/centos/gpg

[docker-ce-test-debuginfo]
name=Docker CE Test - Debuginfo $basearch
baseurl=http://mirrors.ustc.edu.cn/docker-ce/linux/centos/7/debug-$basearch/test
enabled=0
gpgcheck=1
gpgkey=http://mirrors.ustc.edu.cn/docker-ce/linux/centos/gpg

[docker-ce-test-source]
name=Docker CE Test - Sources
baseurl=http://mirrors.ustc.edu.cn/docker-ce/linux/centos/7/source/test
enabled=0
gpgcheck=1
gpgkey=http://mirrors.ustc.edu.cn/docker-ce/linux/centos/gpg

[docker-ce-nightly]
name=Docker CE Nightly - $basearch
baseurl=http://mirrors.ustc.edu.cn/docker-ce/linux/centos/7/$basearch/nightly
enabled=0
gpgcheck=1
gpgkey=http://mirrors.ustc.edu.cn/docker-ce/linux/centos/gpg

[docker-ce-nightly-debuginfo]
name=Docker CE Nightly - Debuginfo $basearch
baseurl=http://mirrors.ustc.edu.cn/docker-ce/linux/centos/7/debug-$basearch/nightly
enabled=0
gpgcheck=1
gpgkey=http://mirrors.ustc.edu.cn/docker-ce/linux/centos/gpg

[docker-ce-nightly-source]
name=Docker CE Nightly - Sources
baseurl=http://mirrors.ustc.edu.cn/docker-ce/linux/centos/7/source/nightly
enabled=0
gpgcheck=1
gpgkey=http://mirrors.ustc.edu.cn/docker-ce/linux/centos/gpg

Kubernetes Repository

  若能访问外网可替换baseurl为:https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64, 阿里的源更新最差会比官方同步慢一天(如果本作者没有理解错本站点所有镜像仓库每天同步一次的意思的话)。

[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0

CentOS Repository

  CentOS的源可按需搜索获取, 或者就使用默认也没问题。

[安装]^(Install)

  主要安装必备组件和docker预pull镜像。

Yum Install

# kubernetes 1.10版本要求docker-ce版本为17.03, 然而其依赖docker-ce-selinux按照对应版本一安装就会自动安装最新版本的docker-ce, 所以无视该警告
# 可以通过yum list docker-ce --showduplicates | sort -r查看其他版本

# 若安装过旧版本docker, 可执行如下语句进行卸载
sudo yum remove -y docker docker-common container-selinux docker-selinux docker-engine

# 更新 安装
sudo yum clean all && yum makecache
sudo yum update -y
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
sudo yum install -y kubectl kubeadm kubelet iptables-services ntp docker-ce

Docker Install

  Docker镜像提前安装准备, 因为网络原因作者把相关镜像pull进了Docker Hub做中转, 方便在kubernetes pull相关镜像失败时, 通过更改yaml或者以kubectl edit的方式更改镜像源以完成安装。
  如果不打算采用作者准备的镜像, 或镜像版本过期太多, 可自行写Dockerfile放到国内镜像仓库构建再拉回来(比如Docker Hub, DaoCloud或者阿里容器仓库), 或者可以配置docker代理来访问(此处可参考[配置]^(Config)一节内容)。

#!/bin/bash

# 必备镜像
docker pull windawings/etcd-amd64:3.2.18
docker pull windawings/k8s-dns-dnsmasq-nanny-amd64:1.14.10
docker pull windawings/k8s-dns-kube-dns-amd64:1.14.10
docker pull windawings/k8s-dns-sidecar-amd64:1.14.10
docker pull windawings/kube-apiserver-amd64:v1.10.2
docker pull windawings/kube-controller-manager-amd64:v1.10.2
docker pull windawings/kube-proxy-amd64:v1.10.2
docker pull windawings/kube-scheduler-amd64:v1.10.2
docker pull windawings/pause-amd64:3.1

# kubernetes dashboard (非SSL版本, 因为port forward没有使用成功过, 采用traefik代理访问界面节点, 而SSL的反向代理比较麻烦需要配置secret等证书信息, 故暂时使用非SSL的部署版本)
docker pull windawings/kubernetes-dashboard-amd64:v1.8.3

# kubernetes 监控相关
docker pull windawings/heapster-amd64:v1.4.2
docker pull windawings/heapster-grafana-amd64:v4.4.3
docker pull windawings/heapster-influxdb-amd64:v1.3.3

# Weave Scope
docker pull weaveworks/scope:1.9.0

# traefik (作代理, 通过nodePort类型的Service与外部建立连接, 用域名访问各节点)
docker pull traefik:latest

# 如果使用calico作为kubernetets cni的话
docker pull quay.io/coreos/etcd:v3.1.10
docker pull quay.io/calico/node:v3.1.1
docker pull quay.io/calico/cni:v3.1.1
docker pull quay.io/calico/kube-controllers:v3.1.1

[配置]^(Config)

  配置CentOS的网络, 以及CentOS下NFS的配置(如果需要kubernetets中nfs服务器的配置项的话, host path的storage class暂时没有尝试成功, 该步骤主要用于配置StatefulSet中Persistent Volumn Claim部分, 使得PV可以自动生成)。

Centos Config

  配置网络, 关闭selinux和firewall, 启用iptables(如果不采用kubernetets的proxy作为网络配置, 使用其他方式实现kubernetets中的网络, 可以考虑不执行以下步骤)。

# 禁用selinux
setenforce 0
sed -i "s/^SELINUX=enforcing/SELINUX=disabled/g" /etc/sysconfig/selinux 
sed -i "s/^SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config 
sed -i "s/^SELINUX=permissive/SELINUX=disabled/g" /etc/sysconfig/selinux 
sed -i "s/^SELINUX=permissive/SELINUX=disabled/g" /etc/selinux/config  

# 禁用firwall 启用iptables
sudo systemctl stop firewalld.service
sudo systemctl disable firewalld.service
sudo systemctl start iptables.service
sudo systemctl enable iptables.service

# 启用网桥中iptables的规则过滤, 因为一者docker默认网桥docker0可能需要, 二者kubernetets自己也是采用iptables做的网络隔离
cat <<EOF >  /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.conf.all.forwarding=1
EOF
sysctl --system

sudo systemctl start ntpd 
sudo systemctl enable ntpd

CentOS Proxy

  配置全局代理, 话是说全局代理, 其实对yum和docker都无效, 甚至wget等……

export HTTPS_PROXY=http://192.168.99.1:1080
export HTTP_PROXY=http://192.168.99.1:1080
export NO_PROXY=localhost,192.168.0.0/16

  取消代理

unset HTTPS_PROXY HTTP_PROXY NO_PROXY

Swap Config

  kubelet禁止在启用swap的环境下运行, 不过可以通过配置kubelet来使其无视, 如果不想无视, 可以通过以下访问禁用swap.

# 卸载swap
swapoff -a && sysctl -w vm.swappiness=0

# 删除swap内容
rm -rf $(swapon -s | awk 'NR>1{print $1}')

# 注释掉swap的挂载
sed -i 's/.*swap.*/#&/' /etc/fstab

NFS Config

  配置CentOS7 NFS. 如果不需要用到kubernetets的nfs挂载可以不用配置。

# 安装
yum install -y nfs-utils nfs-utils-lib rpcbind

# 启用
systemctl enable rpcbind
systemctl enable nfs
systemctl restart rpcbind
systemctl restart nfs

# 创建挂载路径
mkdir -p /pv/cloudera/repo && mkdir /pv/cloudera/master && mkdir /pv/cloudera/agent

# 配置挂载路径到NFS配置中
echo -e "/pv/ *(rw,sync,no_root_squash,no_subtree_check)" >> /etc/exports

# 以上/etc/exports中的配置参数, 这里照搬别人博客的内容, 虽然讲道理没写全
# /pv/ 192.168.0.0/16(rw,sync,no_root_squash,no_subtree_check)
# ro: 目录只读
# rw: 目录读写
# sync: 将数据同步写入内存缓冲区与磁盘中,效率低,但可以保证数据的一致性
# async: 将数据先保存在内存缓冲区中,必要时才写入磁盘
# all_squash: 将远程访问的所有普通用户及所属组都映射为匿名用户或用户组(nfsnobody)
# no_all_squash: 与all_squash取反(默认设置)
# root_squash: 将root用户及所属组都映射为匿名用户或用户组(默认设置)
# no_root_squash: 与rootsquash取反
# anonuid=xxx: 将远程访问的所有用户都映射为匿名用户,并指定该用户为本地用户(UID=xxx)
# anongid=xxx: 将远程访问的所有用户组都映射为匿名用户组账户

# 更改共享目录权限
chown -R nfsnobody.nfsnobody /pv/

# 重载配置
exportfs -rv

# 以下为相关测试项
# 挂载
mount -t nfs 10.0.2.15:/pv/ /root/share

# 卸载
umount /root/share

# 查看挂载情况
showmount -e localhost

# 查看RPC注册情况
rpcinfo -p localhost

Kernel Config

  如果需要的话, 可以升级下CentOS的kernel. 注意, 如果是vagrant虚拟机启动的CentOS box, 升级后vagrant默认的共享挂载会挂(本来出于谨慎想说可能会挂, 但是作者遇到情况就是直接不可用了, 所以如实描述)。

# 准备源
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm

# 安装
yum --enablerepo=elrepo-kernel install -y kernel-ml

# 编辑, 设置其中的GRUB_DEFAULT=0
vi /etc/default/grub

grub2-mkconfig -o /boot/grub2/grub.cfg

# 这里请使用yum list或rpm -qa查询自己旧版本的kernel, 然后删除
yum autoremove kernel-3.10.0-693.11.1.el7.x86_64

# 重启后即可观察到kernel版本的更新

Yum Proxy Config

  如果不采用国内源而试图使用代理, 以下为配置yum的代理。

# 设置proxy=http://<proxy ip>:<proxy port>
vi /etc/yum.conf

Docker Proxy Config

  配置docker代理, NO_PROXY部分把CentOS所在局域网网段加入比较好。当然, 如果能访问k8s.gcr.io谷歌的镜像站点, 则不用配置代理。

sudo mkdir -p /etc/systemd/system/docker.service.d
sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf <<-'EOF'
[Service]
Environment="HTTP_PROXY=http://<proxy ip>:<proxy port>" "HTTPS_PROXY=http://<proxy ip>:<proxy port>" "NO_PROXY=localhost,127.0.0.1,<local ip>/<local mask>, registry.docker-cn.com"
EOF

# 重载配置
sudo systemctl daemon-reload

# 重启docker使得新配置载入
sudo systemctl restart docker

# 配置docker service开机启动
sudo systemctl enable docker

Docker Source Config

  配置docker的镜像源, 可参考daocloud.io, aliyuncs以及其他公有或私有镜像源的配置, 把地址加入registry-mirrors中, 此处使用docker hub作为镜像源。如果默认访问的镜像站点速度不差可无视此项配置。

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://registry.docker-cn.com"]
}
EOF

# 重载配置
sudo systemctl daemon-reload

# 重启docker使得新配置载入
sudo systemctl restart docker

# 配置docker service开机启动
sudo systemctl enable docker

Kubernetes Config

# If the Docker cgroup driver and the kubelet config don’t match, change the kubelet config to match the Docker cgroup driver. The flag you need to change is --cgroup-driver
docker info | grep -i cgroup

# 如果docker info中cgroup=cgroupfs的话, 即可直接使用以下语句进行替换, 不然可按需进行更改
sed -i "s/cgroup-driver=systemd/cgroup-driver=cgroupfs/g" /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

# 配置swap下kubelet的启动, 以及设置pause的镜像
Environment="KUBELET_EXTRA_ARGS=--v=2 --fail-swap-on=false --pod-infra-container-image=windawings/pause-amd64:3.1"

# 若需要修改etcd, apiserver, controller-manager, scheduler镜像位置, 可以稍后启动kubelet, 当kubeadm卡住时替换/etc/kubernetes/manifests中的yaml, 再启动kubelet即可
sudo systemctl restart kubelet

# kubelet开机启动
sudo systemctl enable kubelet.service

[运行]^(Run)

  完成kubeadm init和相关镜像源的修改, 以及其他组件的安装说明。

Kubernetes Net

Tips: 很多时候会存在dns无法连接apiserver的情况, 我只能选择iptables --flush

kubeadm init --pod-network-cidr=192.168.0.0/16
kubectl apply -f "https://docs.projectcalico.org/v3.0/getting-started/kubernetes/installation/hosted/kubeadm/1.7/calico.yaml"
kubeadm init --pod-network-cidr=10.244.0.0/16
kubectl apply -f "https://raw.githubusercontent.com/projectcalico/canal/master/k8s-install/1.7/rbac.yaml"
kubectl apply -f "https://raw.githubusercontent.com/projectcalico/canal/master/k8s-install/1.7/canal.yaml"
kubeadm init --pod-network-cidr=10.244.0.0/16
sysctl net.bridge.bridge-nf-call-iptables=1
kubectl apply -f "https://raw.githubusercontent.com/coreos/flannel/v0.9.1/Documentation/kube-flannel.yml"
#不知道为什么, 不按照官方用0.9.1版本而用最新的DNS就会报错, 以下为报错示范
kubectl apply -f "https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml"
sysctl net.bridge.bridge-nf-call-iptables=1
kubeadm init --pod-network-cidr
sysctl net.bridge.bridge-nf-call-iptables=1
kubectl apply -f "https://raw.githubusercontent.com/romana/romana/master/containerize/specs/romana-kubeadm.yml"
sysctl net.bridge.bridge-nf-call-iptables=1
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"

Kubeadm Init

  需要参照上一节得到需要的pod network cidr. 如果部署出错, 可通过以下指令回滚到初始或者更改配置。

# 回滚到初始
kubeadm reset

# 提交新配置
kubeadm config upload from-file --config <file_name>

# 更新配置(作者更新配置时会遭遇scheduler无限等待重启, 暂时不知如何解决)
kubeadm upgrade apply <k8s_version>

  正常流程如下:

# 作者使用calico维护kubernetets net, 需要注意的是kubeadm init会刷新/etc/kubernetes/中的配置, 所以执行后再去覆盖更换镜像的manifests, 再开启kubelet
# 如果不指定kubernetes-version, 它会去访问google查最新版本, 因为访问不到外网所以最好指定
# token-ttl用于保持连接, 其实没啥连接好保存的, 反正都访问不到
# apiserver-advertise-address可以不要, 设置自己CentOS系统的内网IP即可, 或者CentOS虚拟机的宿主网关IP + 1(指CentOS里面再开虚拟机的操作)
# ignore-preflight-errors忽略开启swap的错误, 包括manifests已存在的警告都忽略
kubeadm init --pod-network-cidr=192.168.0.0/16 --token-ttl 0 --kubernetes-version=1.10.2 --apiserver-advertise-address=192.168.99.100 --ignore-preflight-errors=all

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

sudo tee /etc/profile.d/k8s.sh <<-'EOF'
export KUBECONFIG=/etc/kubernetes/admin.conf
EOF

source /etc/profile.d/k8s.sh

Kubernetes Dashboard

Tips: Dashboard原配的Role和RoleBinding经过traefit之后会没有权限访问任何资源(不经过traefit没有试过, 可能也会被rbac的权限机制干扰), 建议删除Role和RoleBinding部分改为如下直接拿cluster-admin权限岂不美哉。

# ------------------- Dashboard Role & Role Binding ------------------- #
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: kubernetes-dashboard
  labels:
    app: kubernetes-dashboard
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: kubernetes-dashboard
  namespace: kube-system
kubectl create -f "https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/alternative/kubernetes-dashboard.yaml"
kubectl create -f "https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml"

Influxdb

Tips: 如果单节点的话可能无法部署Influxdb和Scope, 会提示node已tainted, pod无法调度部署, 在deployment上加入调度方案即可。或者更新master node的tainted值NoSchedule, 改为PreferNoSchedule或者把tainted删了。

  spec:
    tolerations:
    - key: node-role.kubernetes.io/master # 其实我也不知道这里key代表了什么
    effect: NoSchedule
kubectl apply -f "https://raw.githubusercontent.com/kubernetes/heapster/master/deploy/kube-config/influxdb/grafana.yaml"
kubectl apply -f "https://raw.githubusercontent.com/kubernetes/heapster/master/deploy/kube-config/influxdb/heapster.yaml"
kubectl apply -f "https://raw.githubusercontent.com/kubernetes/heapster/master/deploy/kube-config/influxdb/influxdb.yaml"
kubectl apply -f "https://raw.githubusercontent.com/kubernetes/heapster/master/deploy/kube-config/rbac/heapster-rbac.yaml"

Weave Scope

  动态界面展示Pod, Service, Controller等Kubernetes实体, 颗粒度从Host到Process, 展示同层实体的网络关联, 实时监控CPU和Memory, 可直观手动操作实体, 提供web界面类似docker exec -it /bin/bash的访问模式, 很nice.

kubectl apply -f "https://cloud.weave.works/k8s/scope.yaml?k8s-version=$(kubectl version | base64 | tr -d '\n')"

Traefik

  作者port forward尝试无果后的继承者, 配置Ingress使用域名访问Service.

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

Traefik Config Template

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

[其他]^(Others)

当前页面是本站的「Google AMP」版。查看和发表评论请点击:完整版 »