Kubernetes集群

x33g5p2x  于2021-11-09 转载在 Kubernetes  
字(14.1k)|赞(0)|评价(0)|浏览(270)

Kubernetes

容器自动管理工具、持续部署工具

谷歌的开源工具,开源之前在谷歌内部使用了几年的时间,管理上千万的容器

1.集群方案

使用三台物理机或VMware虚拟机来搭建集群环境,一台主控服务器,两台工作节点服务器。

如果资源有限也可以去掉一个工作节点,使用两台服务器。

2.安装搭建 Kubernetes 集群

安装过程非常复杂,即使对专业运维难度也非常大,有开源工具辅助安装K8s集群

  • 一键安装:https://github.com/easzlab/kubeasz
  • 一步步手动安装:https://github.com/opsnull/follow-me-install-kubernetes-cluster

1.集群安装准备

kubeasz项目(https://github.com/easzlab/kubeasz)极大的简化了k8s集群的安装过程,他提供的工具可以轻松安装和管理k8s集群。

2.主控服务器

先准备主控服务器

调整 VMware 虚拟机的内存和 cpu:

3.下载离线文件,安装Docker

在主控服务器上下载安装环境初始化脚本工具 ezdown:

export release=3.1.0

curl -C- -fLO --retry 3 https://github.com/easzlab/kubeasz/releases/download/${release}/ezdown

chmod +x ./ezdown

ls -l

使用工具脚本下载离线文件,并安装Docker
默认下载最新推荐k8s/docker等版本(更多关于ezdown的参数,运行./ezdown 查看)

./ezdown -D

导入 docker 镜像,后面使用这些镜像用来测试 k8s:

docker load -i images.gz

docker images

可选下载离线系统包 (适用于无法使用yum/apt仓库情形)

./ezdown -P

上述脚本运行成功后,所有文件(kubeasz代码、二进制、离线镜像)均已整理好放入目录/etc/kubeasz

/etc/kubeasz 				包含 kubeasz 版本为 ${release} 的发布代码
/etc/kubeasz/bin 			包含 k8s/etcd/docker/cni 等二进制文件
/etc/kubeasz/down 			包含集群安装时需要的离线容器镜像
/etc/kubeasz/down/packages 	包含集群安装时需要的系统基础软件

安装 python、pip、ansible
ansible 是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。

kubeasz 使用 ansible 来自动安装配置集群,所以这里先要安装 ansible。

yum install python -y

curl -O https://bootstrap.pypa.io/pip/2.7/get-pip.py

python get-pip.py

python -m pip install --upgrade "pip < 21.0"

pip install ansible -i https://mirrors.aliyun.com/pypi/simple/

4.工作节点

在工作节点服务器上重复以上所有操作。

如果使用 VMware 虚拟机,只需要从第一台服务器克隆即可。

二,配置集群安装环境

启动 kubeasz 容器

./ezdown -S

设置参数允许离线安装

sed -i 's/^INSTALL_SOURCE.*$/INSTALL_SOURCE: "offline"/g' /etc/kubeasz/example/config.yml

第一台服务器**

  1. 克隆 centos-8-2105: k1
  2. 设置ip
./ip-static
ip: 192.168.64.191

ifconfig
  1. kubeasz-3.1.0.zip 解压缩
  • 上传文件

  • images.gz 上传到 /root/

  • kubeasz-3.1.0/ezdown 上传到 /root/

  • kubeasz-3.1.0/kubeasz 文件夹上传到 /etc/

  • 内存设置 2G 或 2G 以上

  • cpu 设置成两块

  • 重启服务器

准备安装环境

cd ~/
chmod +x ./ezdown

# 1.下载离线安装文件,如果存在,不会重复下载
# 2.安装Docker
./ezdown -D

docker info

docker load -i images.gz

docker images

克隆 k1,克隆出 k2 和 k3

  • k1先关机

  • 方案1,从 k1 克隆出 k2 和 k3

  • 方法2,从 k1 只克隆一个 k2

  • 修改 k2 和 k3 的 ip

  • 192.168.64.192

  • 192.168.64.193

三.Kubernetes

安装kubernetes集群

kubernetes的安装过程极其复杂,对Linux运维不熟悉的情况下安装kubernetes极为困难,再加上国内无法访问google服务器,我们安装k8s就更加困难

kubeasz项目(https://github.com/easzlab/kubeasz)极大的简化了k8s集群的安装过程,使我们可以离线一键安装k8s集群

准备第一台虚拟机

设置虚拟机cpu

上传离线安装文件

将ansible目录上传到/etc/目录下

将easzup上传到/root目录下

准备离线安装环境

在CentOS7虚拟机中执行下面操作

cd ~/

# 下载 kubeasz 的自动化安装脚本文件: easzup,如果已经上传过此文件,则不必执行这一步
export release=2.2.0
curl -C- -fLO --retry 3 https://github.com/easzlab/kubeasz/releases/download/${release}/easzup

# 对easzup文件设置执行权限
chmod +x ./easzup

# 下载离线安装文件,并安装配置docker,
# 如果离线文件已经存在则不会重复下载,
# 离线安装文件存放路径: /etc/ansible
./easzup -D

验证Docker系统服务:

docker version

# 启动kubeasz工具使用的临时容器
./easzup -S

查看临时容器:

docker ps

# 进入该容器
docker exec -it kubeasz sh

# 下面命令在容器内执行
# 配置离线安装
cd /etc/ansible
sed -i 's/^INSTALL_SOURCE.*$/INSTALL_SOURCE: "offline"/g' roles/chrony/defaults/main.yml
sed -i 's/^INSTALL_SOURCE.*$/INSTALL_SOURCE: "offline"/g' roles/ex-lb/defaults/main.yml
sed -i 's/^INSTALL_SOURCE.*$/INSTALL_SOURCE: "offline"/g' roles/kube-node/defaults/main.yml
sed -i 's/^INSTALL_SOURCE.*$/INSTALL_SOURCE: "offline"/g' roles/prepare/defaults/main.yml
exit

# 安装 python,已安装则忽略这一步
yum install python -y

导入镜像

为了节省时间,后面课程中使用的docker镜像不用再花时间从网络下载

将课前资料中 images.gz 中的镜像导入 docker

docker load -i images.gz

准备三台服务器

准备三台服务器,一台master,两台工作节点,他们的ip地址可以用任意的地址,最好设置为固定ip

下面测试中使用的ip为:

  • 192.168.64.191
  • 192.168.64.192
  • 192.168.64.193

从第一台虚拟机克隆两台虚拟机

这三台虚拟机,第一台虚拟机作为master,另两台作为工作节点

在master上继续配置安装环境

# 安装pip,已安装则忽略这一步
wget -O /etc/yum.repos.d/epel-7.repo https://mirrors.aliyun.com/repo/epel-7.repo
yum install git python-pip -y

# pip安装ansible(国内如果安装太慢可以直接用pip阿里云加速),已安装则忽略这一步
pip install pip --upgrade -i https://mirrors.aliyun.com/pypi/simple/
pip install ansible==2.6.12 netaddr==0.7.19 -i https://mirrors.aliyun.com/pypi/simple/

# 在ansible控制端配置免密码登陆其他节点服务器
ssh-keygen -t ed25519 -N '' -f ~/.ssh/id_ed25519

# 公钥复制到所有节点,包括master自己
# 按提示输入yes和root管理员的密码
ssh-copy-id 192.168.64.191

ssh-copy-id 192.168.64.192

ssh-copy-id 192.168.64.193

配置集群服务器的ip

cd /etc/ansible && cp example/hosts.multi-node hosts && vim hosts

如果内存有限, 可以只部署两台服务器进行测试

主服务器既作为控制节点, 又作为工作节点
减少etcd服务数量

# 检查集群主机状态
ansible all -m ping

一键安装k8s集群

安装步骤非常多,时间较长,耐心等待安装完成

cd /etc/ansible
ansible-playbook 90.setup.yml

安装成功结果:

设置kubectl命令别名

# 设置 kubectl 命令别名 k
echo "alias k='kubectl'" >> ~/.bashrc

# 使设置生效
source ~/.bashrc

配置自动补全

yum install -y bash-completion

source <(kubectl completion bash)

echo "source <(kubectl completion bash)" >> ~/.bashrc

source ~/.bashrc

验证安装

k get cs
---------------------------------------------------------
NAME                 STATUS    MESSAGE             ERROR
etcd-1               Healthy   {"health":"true"}   
scheduler            Healthy   ok                  
controller-manager   Healthy   ok                  
etcd-2               Healthy   {"health":"true"}   
etcd-0               Healthy   {"health":"true"}   

k get node
---------------------------------------------------------------------
NAME             STATUS                     ROLES    AGE     VERSION
192.168.64.191   Ready,SchedulingDisabled   master   5d23h   v1.15.2
192.168.64.192   Ready                      node     5d23h   v1.15.2
192.168.64.193   Ready                      node     5d23h   v1.15.2

初步尝试 kubernetes

kubectl run 命令是最简单的部署引用的方式,它自动创建必要组件,这样,我们就先不必深入了解每个组件的结构

使用 ReplicationController 和 pod 部署应用

Pod是用来封装Docker容器的对象,它具有自己的虚拟环境(端口, 环境变量等),一个Pod可以封装多个Docker容器.

RC是用来自动控制Pod部署的工具,它可以自动启停Pod,对Pod进行自动伸缩.

下面我们用命令部署一个RC

cd ~/

k run \
    --image=luksa/kubia \
    --port=8080 \
    --generator=run/v1 kubia

k get rc
---------------------------------------
NAME    DESIRED   CURRENT   READY   AGE
kubia   1         1         1       24s

k get pods
----------------------------------------------
NAME          READY   STATUS    RESTARTS   AGE
kubia-9z6kt   1/1     Running   0          28s

kubectl run 几个参数的含义

–image=luksa/kubia

  • 镜像名称
    –port=8080
  • pod 对外暴露的端口
    –generator=run/v1 kubia
    创建一个ReplicationController

使用 service 对外暴露 pod

k expose \
    rc kubia \
    --type=NodePort \
    --name kubia-http

k get svc
------------------------------------------------------------------------------
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubia-http   NodePort    10.68.194.195   <none>        8080:20916/TCP   4s

这里创建了一个 service 组件,用来对外暴露pod访问,在所有节点服务器上,暴露了20916端口,通过此端口,可以访问指定pod的8080端口

访问以下节点服务器的20916端口,都可以访问该应用

注意: 要把端口修改成你生成的随机端口

  • http://192.168.64.191:20916/
  • http://192.168.64.192:20916/
  • http://192.168.64.193:20916/

pod自动伸缩

k8s对应用部署节点的自动伸缩能力非常强,只需要指定需要运行多少个pod,k8s就可以完成pod的自动伸缩

# 将pod数量增加到3个
k scale rc kubia --replicas=3

k get po -o wide
----------------------------------------------------------------------------------------------------------------
NAME          READY   STATUS    RESTARTS   AGE   IP            NODE             NOMINATED NODE   READINESS GATES
kubia-q7bg5   1/1     Running   0          10s   172.20.3.29   192.168.64.193   <none>           <none>
kubia-qkcqh   1/1     Running   0          10s   172.20.2.30   192.168.64.192   <none>           <none>
kubia-zlmsn   1/1     Running   0          16m   172.20.3.28   192.168.64.193   <none>           <none>

# 将pod数量减少到1个
k scale rc kubia --replicas=1

# k8s会自动停止两个pod,最终pod列表中会只有一个pod
k get po -o wide
---------------------------------------------------------------------------------------------------------------------
NAME          READY   STATUS        RESTARTS   AGE    IP            NODE             NOMINATED NODE   READINESS GATES
kubia-q7bg5   1/1     Terminating   0          6m1s   172.20.3.29   192.168.64.193   <none>           <none>
kubia-qkcqh   1/1     Terminating   0          6m1s   172.20.2.30   192.168.64.192   <none>           <none>
kubia-zlmsn   1/1     Running       0          22m    172.20.3.28   192.168.64.193   <none>           <none>

pod

使用部署文件手动部署pod

创建kubia-manual.yml部署文件

cat <<EOF > kubia-manual.yml apiVersion: v1 # k8s api版本 kind: Pod # 该部署文件用来创建pod资源 metadata: name: kubia-manual # pod名称前缀,后面会追加随机字符串 spec: containers: # 对pod中容器的配置 - image: luksa/kubia # 镜像名 imagePullPolicy: Never name: kubia # 容器名 ports: - containerPort: 8080 # 容器暴露的端口 protocol: TCP EOF

使用部署文件创建pod

k create -f kubia-manual.yml

k get po
-----------------------------------------------
NAME           READY   STATUS    RESTARTS   AGE
kubia-manual   1/1     Running   0          19s

查看pod的部署文件

# 查看pod的部署文件
k get po kubia-manual -o yaml

查看pod日志

k logs kubia-manual

pod端口转发

使用 kubectl port-forward 命令设置端口转发,对外暴露pod.

使用服务器的 8888 端口,映射到 pod 的 8080 端口

k port-forward kubia-manual --address localhost,192.168.64.191 8888:8080

# 或在所有网卡上暴露8888端口
k port-forward kubia-manual --address 0.0.0.0 8888:8080

在浏览器中访问 http://192.168.64.191:8888/

pod 标签

可以为 pod 指定标签,通过标签可以对 pod 进行分组管理

ReplicationController,ReplicationSet,Service中,都可以通过 Label 来分组管理 pod

创建pod时指定标签

通过kubia-manual-with-labels.yml部署文件部署pod

在部署文件中为pod设置了两个自定义标签:creation_method和env

cat <<EOF > kubia-manual-with-labels.yml apiVersion: v1 # api版本 kind: Pod # 部署的资源类型 metadata: name: kubia-manual-v2 # pod名 labels: # 标签设置,键值对形式 creation_method: manual env: prod spec: containers: # 容器设置 - image: luksa/kubia # 镜像 name: kubia # 容器命名 imagePullPolicy: Never ports: # 容器暴露的端口 - containerPort: 8080 protocol: TCP EOF

使用部署文件创建资源

k create -f kubia-manual-with-labels.yml

查看pod的标签

列出所有的pod,并显示pod的标签

k get po --show-labels
------------------------------------------------------------
NAME              READY   STATUS    RESTARTS   AGE    LABELS
kubia-5rz9h       1/1     Running   0          109s   run=kubia
kubia-manual      1/1     Running   0          52s    <none>
kubia-manual-v2   1/1     Running   0          10s    creation_method=manual,env=prod

以列的形式列出pod的标签

k get po -L creation_method,env
-----------------------------------------------------------------------------
NAME              READY   STATUS    RESTARTS   AGE     CREATION_METHOD   ENV
kubia-5rz9h       1/1     Running   0          4m19s                     
kubia-manual      1/1     Running   0          3m22s                     
kubia-manual-v2   1/1     Running   0          2m40s   manual            prod

修改pod的标签

pod kubia-manual-v2 的env标签值是prod, 我们把这个标签的值修改为 debug

修改一个标签的值时,必须指定 --overwrite 参数,目的是防止误修改

k label po kubia-manual-v2 env=debug --overwrite

k get po -L creation_method,env
---------------------------------------------------------------------------
NAME              READY   STATUS    RESTARTS   AGE   CREATION_METHOD   ENV
kubia-5rz9h       1/1     Running   0          15m                     
kubia-manual      1/1     Running   0          14m                     
kubia-manual-v2   1/1     Running   0          13m   manual            debug

为pod kubia-manual 设置标签

k label po kubia-manual creation_method=manual env=debug

为pod kubia-5rz9h 设置标签

k label po kubia-5rz9h env=debug

查看标签设置的结果

k get po -L creation_method,env
--------------------------------------------------------------------------
AME              READY   STATUS    RESTARTS   AGE   CREATION_METHOD   ENV
kubia-5rz9h       1/1     Running   0          18m                     debug
kubia-manual      1/1     Running   0          17m   manual            debug
kubia-manual-v2   1/1     Running   0          16m   manual            debug

使用标签来查询 pod

查询 creation_method=manual 的pod

# -l 查询
k get po \
    -l creation_method=manual \
    -L creation_method,env
---------------------------------------------------------------------------
NAME              READY   STATUS    RESTARTS   AGE   CREATION_METHOD   ENV
kubia-manual      1/1     Running   0          28m   manual            debug
kubia-manual-v2   1/1     Running   0          27m   manual            debug

查询有 env 标签的 pod

# -l 查询
k get po \
    -l env \
    -L creation_method,env
---------------------------------------------------------------------------
NAME              READY   STATUS    RESTARTS   AGE   CREATION_METHOD   ENV
kubia-5rz9h       1/1     Running   0          31m                     debug
kubia-manual      1/1     Running   0          30m   manual            debug
kubia-manual-v2   1/1     Running   0          29m   manual            debug

查询 creation_method=manual 并且 env=debug 的 pod

# -l 查询
k get po \
    -l creation_method=manual,env=debug \
    -L creation_method,env
---------------------------------------------------------------------------
NAME              READY   STATUS    RESTARTS   AGE   CREATION_METHOD   ENV
kubia-manual      1/1     Running   0          33m   manual            debug
kubia-manual-v2   1/1     Running   0          32m   manual            debug

其他查询举例:

  • creation_method!=manual
  • env in (prod,debug)
  • env notin (prod,debug)

把pod部署到指定的节点服务器

我们不能直接指定服务器的地址来约束pod部署的节点

通过为node设置标签,在部署pod时,使用节点选择器,来选择把pod部署到匹配的节点服务器

下面为名称为192.168.64.193的节点服务器,添加标签gpu=true

k label node \
    192.168.64.193 \
    gpu=true

k get node \
    -l gpu=true \
    -L gpu
------------------------------------------------------
NAME             STATUS   ROLES   AGE   VERSION   GPU
192.168.64.193   Ready    node    14d   v1.15.2   true

部署文件,其中节点选择器nodeSelector设置了通过标签gpu=true来选择节点

cat <<EOF > kubia-gpu.yml apiVersion: v1 kind: Pod metadata: name: kubia-gpu # pod名 spec: nodeSelector: # 节点选择器,把pod部署到匹配的节点 gpu: "true" # 通过标签 gpu=true 来选择匹配的节点 containers: # 容器配置 - image: luksa/kubia # 镜像 name: kubia # 容器名 imagePullPolicy: Never EOF

创建pod kubia-gpu,并查看pod的部署节点

k create -f kubia-gpu.yml

k get po -o wide
----------------------------------------------------------------------------------------------------------------------
NAME              READY   STATUS    RESTARTS   AGE     IP            NODE             NOMINATED NODE   READINESS GATES
kubia-5rz9h       1/1     Running   0          3m13s   172.20.2.35   192.168.64.192   <none>           <none>
kubia-gpu         1/1     Running   0          8m7s    172.20.3.35   192.168.64.193   <none>           <none>
kubia-manual      1/1     Running   0          58m     172.20.3.33   192.168.64.193   <none>           <none>
kubia-manual-v2   1/1     Running   0          57m     172.20.3.34   192.168.64.193   <none>           <none>

查看pod kubia-gpu的描述

k describe po kubia-gpu
------------------------------------------------
Name:         kubia-gpu
Namespace:    default
Priority:     0
Node:         192.168.64.193/192.168.64.193
......

pod 注解

可以为资源添加注解

注解不能被选择器使用

# 注解
k annotate pod kubia-manual tedu.cn/shuoming="foo bar"

k describe po kubia-manual

namespace

可以使用命名空间对资源进行组织管理

不同命名空间的资源并不完全隔离,它们之间可以通过网络互相访问

查看命名空间

# namespace
k get ns

k get po --namespace kube-system
k get po -n kube-system

创建命名空间

新建部署文件custom-namespace.yml,创建命名空间,命名为custom-namespace

cat <<EOF > custom-namespace.yml
apiVersion: v1
kind: Namespace
metadata:
  name: custom-namespace
EOF
# 创建命名空间
k create -f custom-namespace.yml 

k get ns
--------------------------------
NAME               STATUS   AGE
custom-namespace   Active   2s
default            Active   6d
kube-node-lease    Active   6d
kube-public        Active   6d
kube-system        Active   6d

将pod部署到指定的命名空间中

创建pod,并将其部署到命名空间custom-namespace

# 创建 Pod 时指定命名空间
k create \
    -f kubia-manual.yml \
    -n custom-namespace

# 默认访问default命名空间,默认命名空间中不存在pod kubia-manual
k get po kubia-manual

# 访问custom-namespace命名空间中的pod
k get po kubia-manual -n custom-namespace
----------------------------------------------------------
NAME           READY   STATUS              RESTARTS   AGE
kubia-manual   0/1     ContainerCreating   0          59s

删除资源

# 按名称删除, 可以指定多个名称
# 例如: k delete po po1 po2 po3
k delete po kubia-gpu

# 按标签删除
k delete po -l creation_method=manual

# 删除命名空间和其中所有的pod
k delete ns custom-namespace

# 删除当前命名空间中所有pod
k delete po --all

# 由于有ReplicationController,所以会自动创建新的pod
[root@master1 ~]# k get po
NAME          READY   STATUS    RESTARTS   AGE
kubia-m6k4d   1/1     Running   0          2m20s
kubia-rkm58   1/1     Running   0          2m15s
kubia-v4cmh   1/1     Running   0          2m15s

# 删除工作空间中所有类型中的所有资源
# 这个操作会删除一个系统Service kubernetes,它被删除后会立即被自动重建
k delete all --all

存活探针

有三种存活探针:

  • HTTP GET

返回 2xx 或 3xx 响应码则认为探测成功

  • TCP

与指定端口建立 TCP 连接,连接成功则为成功

  • Exec

在容器内执行任意的指定命令,并检查命令的退出码,退出码为0则为探测成功

HTTP GET 存活探针

luksa/kubia-unhealthy 镜像

在kubia-unhealthy镜像中,应用程序作了这样的设定: 从第6次请求开始会返回500错

在部署文件中,我们添加探针,来探测容器的健康状态.

探针默认每10秒探测一次,连续三次探测失败后重启容器

cat <<EOF > kubia-liveness-probe.yml apiVersion: v1 kind: Pod metadata: name: kubia-liveness # pod名称 spec: containers: - image: luksa/kubia-unhealthy # 镜像 name: kubia # 容器名 imagePullPolicy: Never livenessProbe: # 存活探针配置 httpGet: # HTTP GET 类型的存活探针 path: / # 探测路径 port: 8080 # 探测端口 EOF

创建 pod

k create -f kubia-liveness-probe.yml

# pod的RESTARTS属性,每过1分半种就会加1
k get po kubia-liveness
--------------------------------------------------
NAME             READY   STATUS    RESTARTS   AGE
kubia-liveness   1/1     Running   0          5m25s

查看上一个pod的日志,前5次探测是正确状态,后面3次探测是失败的,则该pod会被删除

k logs kubia-liveness --previous
-----------------------------------------
Kubia server starting...
Received request from ::ffff:172.20.3.1
Received request from ::ffff:172.20.3.1
Received request from ::ffff:172.20.3.1
Received request from ::ffff:172.20.3.1
Received request from ::ffff:172.20.3.1
Received request from ::ffff:172.20.3.1
Received request from ::ffff:172.20.3.1
Received request from ::ffff:172.20.3.1

查看pod描述

k describe po kubia-liveness
---------------------------------
......
    Restart Count:  6
    Liveness:       http-get http://:8080/ delay=0s timeout=1s period=10s #success=1 #failure=3
......

相关文章

微信公众号