深入Kubernetes(一):Kubernetes部署&在Kubernetes中运行第一个程序


搭建Kubernetes单点实验环境

由于在国内网络问题,我们无法很好的使用Minikube进行部署Kubernetes实验环境,所以可以使用阿里提供的minikube进行搭建。除了minikube,也可以使用kubeasz进行部署。

下面我基于kubeaze给出部署方法,部署方法都参照https://github.com/easzlab/kubeasz,其中附上我的踩坑经验。

基础系统配置

  • 准备一台虚机配置内存2G/硬盘30G以上
  • 最小化安装Ubuntu 16.04 server或者CentOS 7 Minimal
  • 配置基础网络、更新源、SSH登录等


注意:确保在干净的系统上开始安装,不能使用曾经装过kubeadm或其他Kubernetes发行版的环境

下载文件

下载工具脚本easzup,举例使用kubeasz版本2.2.1。
export release=2.2.1
curl -C- -fLO --retry 3 https://github.com/easzlab/kubeasz/releases/download/${release}/easzup
chmod +x ./easzup

使用工具脚本下载。

默认下载最新推荐Kubernetes/Docker等版本,使用命令./easzup查看工具脚本的帮助信息。

设置Docker源:
{
"registry-mirrors": [
"https://eig40bb2.mirror.aliyuncs.com",
"https://docker.mirrors.ustc.edu.cn",
"http://hub-mirror.c.163.com",
"https://reg-mirror.qiniu.com"
],
"max-concurrent-downloads": 10,
"log-driver": "json-file",
"log-level": "warn",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"data-root": "/var/lib/docker"


添加完之后刷新一下配置:
systemctl daemon-reload
systemctl restart docker

# 举例使用 Kubernetes 版本 v1.18.2,Docker 19.03.5
./easzup -D -d 19.03.5 -k v1.18.2

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

上述脚本运行成功后,所有文件(kubeasz代码、二进制、离线镜像)均已整理好放入目录/etc/ansible。
  • /etc/ansible包含kubeasz版本为${release}的发布代码
  • /etc/ansible/bin包含Kubernetes/etcd/Docker/CNI等二进制文件
  • /etc/ansible/down包含集群安装时需要的离线容器镜像
  • /etc/ansible/down/packages包含集群安装时需要的系统基础软件


安装集群

容器化运行 kubeasz。
./easzup -S

使用默认配置安装aio集群。
docker exec -it kubeasz easzctl start-aio

验证安装

如果提示kubectl: command not found,退出重新SSH登录一下,环境变量生效即可。
$ kubectl version         # 验证集群版本     
$ kubectl get node        # 验证节点就绪(Ready)状态
$ kubectl get pod -A      # 验证集群Pod状态,默认已安装网络插件、coredns、metrics-server等
$ kubectl get svc -A      # 验证集群服务状态

搭建Kubernetes集群环境

我们打算搭建一个这样的三节点的集群:
1.png

准备服务器

首先3台虚机,搭建一个多主高可用集群。
  • 推荐内存2G/硬盘30G以上
  • 最小化安装Ubuntu 16.04 server或者CentOS 7 Minimal
  • 配置基础网络、更新源、SSH登录等


在每个节点安装Ansible依赖工具

CentOS 7请执行以下脚本:
# 文档中脚本默认均以root用户执行
yum update
# 安装Python
yum install python -y

安装pip的时候先安装。
yum -y install epel-release

安装pip。
yum install git python-pip -y

pip安装Ansible。
# CentOS 7
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.18 netaddr==0.7.19 -i https://mirrors.aliyun.com/pypi/simple/

在Ansible控制端配置免密码登录。
# 更安全Ed25519算法
ssh-keygen -t ed25519 -N '' -f ~/.ssh/id_ed25519
# 或者传统RSA算法
ssh-keygen -t rsa -b 2048 -N '' -f ~/.ssh/id_rsa

ssh-copy-id 192.168.13.131
ssh-copy-id 192.168.13.132
ssh-copy-id 192.168.13.133

如果这一步不设置,那么在部署的时候无法访问到相应的节点会报如下错:
192.168.13.130 | UNREACHABLE! => {
"changed": false,
"msg": "SSH Error: data could not be sent to remote host \"192.168.13.130\". Make sure this host can be reached over ssh",
"unreachable": true


在Ansible控制端编排Kubernetes安装

  • 下载项目源码
  • 下载二进制文件
  • 下载离线Docker镜像


推荐使用easzup脚本下载4.0/4.1/4.2所需文件;运行成功后,所有文件(kubeasz代码、二进制、离线镜像)均已整理好放入目录/etc/ansible。
# 下载工具脚本easzup,举例使用kubeasz版本2.0.2
export release=2.0.2
curl -C- -fLO --retry 3 https://github.com/easzlab/kubeasz/releases/download/${release}/easzup
chmod +x ./easzup
# 使用工具脚本下载
./easzup -D

配置集群参数

必要配置:cd/etc/ansible && cp example/hosts.multi-node hosts,然后实际情况修改此hosts文件。

根据我们上图的介绍,我们将hosts改成如下:
# 'etcd' cluster should have odd member(s) (1,3,5,...)
# variable 'NODE_NAME' is the distinct name of a member in 'etcd' cluster
[etcd]
192.168.13.131 NODE_NAME=etcd1
192.168.13.132 NODE_NAME=etcd2
192.168.13.133 NODE_NAME=etcd3

# master node(s)
[kube-master]
192.168.13.131

# work node(s)
[kube-node]
192.168.13.131
192.168.13.132
192.168.13.133

...

只改如上配置,其他的可不动。

验证Ansible安装:ansible all -m ping正常能看到节点返回SUCCESS。

开始安装,如果你对集群安装流程不熟悉,请阅读项目首页安装步骤,讲解后分步安装,并对每步都进行验证。
# 分步安装
ansible-playbook 01.prepare.yml
ansible-playbook 02.etcd.yml
ansible-playbook 03.docker.yml
ansible-playbook 04.kube-master.yml
ansible-playbook 05.kube-node.yml
ansible-playbook 06.network.yml
ansible-playbook 07.cluster-addon.yml

如果不想分步安装,那么可以一步安装:
# 一步安装
#ansible-playbook 90.setup.yml

在Kubernetes中运行一个程序

编写YAML文件

Kubernetes跟Docker等很多项目最大的不同,就在于它不推荐你使用命令行的方式直接运行容器,而是希望你用YAML文件的方式,然后用这样一句指令把它运行起来:
$ kubectl create -f 我的配置文件

yaml如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
  app: nginx
replicas: 2
template:
metadata:
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.7.9
    ports:
    - containerPort: 80

Kind字段,指定了这个API对象的类型(Type),是一个Deployment。Deployment,是一个定义多副本应用的对象,Deployment还负责在Pod定义发生变化时,对每个副本进行滚动更新。

像这样使用一种API对象(Deployment)管理另一种API对象(Pod)的方法,在Kubernetes中,叫作“控制器”模式(controller pattern)。

一个Kubernetes的API对象的定义,大多可以分为Metadata和Spec两个部分。前者存放的是这个对象的元数据,对所有API对象来说,这一部分的字段和格式基本上是一样的;而后者存放的,则是属于这个对象独有的定义,用来描述它所要表达的功能。

spec.replicas是2,表示定义的 Pod 副本个数。

spec.template作用是描述了我想要创建的 Pod 的细节。spec.containers.image表示容器镜像是nginx:1.7.9,containerPort表示监听的端口是80。

Labels字段可以用来过滤控制对象,在上面这个YAML文件中,Deployment会把所有正在运行的、携带“app: nginx”标签的Pod识别为被管理的对象,并确保这些Pod的总数严格等于两个。

spec.selector.matchLabels是用来定义过滤规则的,一般称之为:Label Selector。

创建一个Pod

在理解完上面的知识后,我们可以运行起来:
$ kubectl create -f nginx-deployment.yaml

然后,通过kubectl get命令检查这个YAML运行起来的状态是不是与我们预期的一致:
$ kubectl get pods -l app=nginx
NAME                                READY     STATUS    RESTARTS   AGE
nginx-deployment-67594d6bf6-9gdvr   1/1       Running   0          10m
nginx-deployment-67594d6bf6-v6j7w   1/1       Running   0          10m

-l表示获取所有匹配app: nginx标签的Pod。

注意:在命令行中,所有key-value格式的参数,都使用“=”而非“:”表示。

此外,我们还可以使用kubectl describe命令,查看一个API对象的细节:
$ kubectl describe pod nginx-deployment-67594d6bf6-9gdvr
Name:               nginx-deployment-67594d6bf6-9gdvr
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               node-1/10.168.0.3
Start Time:         Thu, 16 Aug 2018 08:48:42 +0000
Labels:             app=nginx
                pod-template-hash=2315082692
Annotations:        <none>
Status:             Running
IP:                 10.32.0.23
Controlled By:      ReplicaSet/nginx-deployment-67594d6bf6
...
Events:

Type     Reason                  Age                From               Message

----     ------                  ----               ----               -------

Normal   Scheduled               1m                 default-scheduler  Successfully assigned default/nginx-deployment-67594d6bf6-9gdvr to node-1
Normal   Pulling                 25s                kubelet, node-1    pulling image "nginx:1.7.9"
Normal   Pulled                  17s                kubelet, node-1    Successfully pulled image "nginx:1.7.9"
Normal   Created                 17s                kubelet, node-1    Created container
Normal   Started                 17s                kubelet, node-1    Started container

上面详细信息中,在Kubernetes执行的过程中,对API对象的所有重要操作都会记录到Events里面。

为Pod进行版本升级

如果我们要对这个Nginx服务进行升级,把它的镜像版本从1.7.9升级为1.8,那么我们可以修改一下YAML文件:
...    
spec:
  containers:
  - name: nginx
    image: nginx:1.8 #这里被从1.7.9修改为1.8
    ports:
  - containerPort: 80

然后使用kubectl replace指令来完成Kubernetes集群中更新:
$ kubectl replace -f nginx-deployment.yaml

我们也可以使用kubectl apply命令,来统一进行Kubernetes对象的创建和更新操作,具体做法如下所示:
$ kubectl apply -f nginx-deployment.yaml

# 修改nginx-deployment.yaml的内容

$ kubectl apply -f nginx-deployment.yaml

使用kubectl apply命令是Kubernetes“声明式API”所推荐的使用方法。也就是说,作为用户,你不必关心当前的操作是创建,还是更新,你执行的命令始终是kubectl apply,而Kubernetes则会根据YAML文件的内容变化,自动进行具体的处理。

声明一个Volume

在Kubernetes中,Volume是属于Pod对象的一部分。所以,我们就需要修改这个YAML文件里的template.spec字段,如下所示:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
  app: nginx
replicas: 2
template:
metadata:
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.8
    ports:
    - containerPort: 80
    volumeMounts:
    - mountPath: "/usr/share/nginx/html"
      name: nginx-vol
  volumes:
  - name: nginx-vol
    emptyDir: {} 

我们在上面定义了volumes字段,名字叫做nginx-vol,类型是emptyDir。Pod中的容器,使用的是volumeMounts字段来声明自己要挂载哪个Volume,并通过mountPath字段来定义容器内的Volume目录,比如:/usr/share/nginx/html。

emptyDir表示,Kubernetes也会在宿主机上创建一个临时目录,这个目录将来就会被绑定挂载到容器所声明的Volume目录上。

然后使用kubectl apply 指令,更新这个Deployment,然后使用kubectl describe查看一下最新的Pod:
...
Containers:
nginx:
Container ID:   docker://07b4f89248791c2aa47787e3da3cc94b48576cd173018356a6ec8db2b6041343
Image:          nginx:1.8
...
Environment:    <none>
Mounts:
  /usr/share/nginx/html from nginx-vol (rw)
...
Volumes:
nginx-vol:
Type:    EmptyDir (a temporary directory that shares a pod's lifetime)

最后,你还可以使用kubectl exec指令,进入到这个Pod当中(即容器的Namespace中)查看这个Volume目录:
$ kubectl exec -it nginx-deployment-5c678cfb6d-lg9lw -- /bin/bash
# ls /usr/share/nginx/html

如果要删除这个Nginx Deployment 的话,直接执行:
$ kubectl delete -f nginx-deployment.yaml

总结

  • 与Kubernetes进行交互尽量选择yaml文件交互;
  • 我们可以使用kubectl create 命令创建一个Pod;
  • 想要获取目前Pod的状态可以使用kubectl get pods命令;
  • 使用kubectl describe pod可以查看某个Pod的详细信息;
  • 如果想要对Pod更新最好使用kubectl apply -f,这样可以做到更加无感的创建Pod或更新;
  • 我们可以使用Volumes来挂载卷;
  • 使用kubectl delete -f可以删除一个Pod。


原文链接:https://www.cnblogs.com/luozhiyun/p/13351499.html,作者:luozhiyun

0 个评论

要回复文章请先登录注册