【使用kubeadm快速部署k8s集群】

安装要求:

1、操作系统 7.4~7.8,本机是7.6

$ cat /etc/redhat-release

CentOS Linux release 7.6.1810 (Core)

# 可以使用yum命令对系统进行升级

$ yum update -y

2、硬件:本机虚拟机2C2G

3、集群服务器互通,可以访问外网,需要拉取镜像

如果不能连接外网,可以使用docker load

4、禁止swap分区

目录

1、准备环境

2、安装Docker

3、安装kubeadm,kubelet和kubectl

4、部署K8s master

5、部署K8s node

6、部署dashboard

7、制作镜像

8、发布升级

9、水平扩容、缩容

10、应用下线

11、使用控制器部署Docker镜像


1、准备环境

# 关闭防火墙

centos7 -> firewalld 主推此,不再用iptables,但是仍可以用

centos6 -> iptables

# 关闭防火墙,三台虚拟机都要设置,这一步操作是为了防止在学习阶段由于防火墙造成的各种网络问题,生产环境跳过这一步,

$ systemctl stop firewall

$ systemctl disable firewalld

$ systemctl status firewalld.service

# 关闭selinux

$ setenforce 0 # 临时

$ sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config # 永久

# 关闭分区

linux默认的,内存不足时,用磁盘来做数据交换。

磁盘传输数据效率很差,为避免使用磁盘来做数据交换,k8s要求尽量不使用交换区,都使用内存,防止出现预料之外的问题。

$ swapoff -a # 临时关闭

$ vi /etc/fstab # 永久关闭。注释swap一行

#/dev/mapper/centos-swap swap swap defaults 0 0

$ free -m # 查看分区

# 配置hosts

$ hostnamectl set-hostname master1 # master1执行

$ hostnamectl set-hostname node1 # node1执行

$ hostnamectl set-hostname node2 # node2执行

$ cat >> /etc/hosts <<EOF

192.168.43.23 master1

192.168.43.25 node1

192.168.43.24 node2

EOF

# 或者vim修改添加master和node映射

$ vim /etc/hosts

# 网络桥接配置

# 将桥接的ipv4流量传递到iptables的链 (master、node)

$ cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf

net.bridge.bridge-nf-call-ip6tables = 1

net.bridge.bridge-nf-call-iptables = 1

EOF

$ sudo sysctl --system # 生效

# 时间同步配置

# 时区一致

$ timedatectl set-timezone Asia/Shanghai

$ yum install ntpdate

# 时间同步 第一个不可用,则使用第二个pool.ntp.org

$ ntpdate time.window.com

$ ntpdate pool.ntp.org

2、安装Docker

$ yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

$ yum install -y docker-ce

$ docker --version # 版本 Server Version: 20.10.10

$ systemctl status docker # docker状态

# 配置docker加速器

$ cat > /etc/docker/daemon.json <<EOF

{

"registry-mirrors":["https://4ojlwa2w.mirror.aliyuncs.com"]

}

EOF

$ systemctl daemon-reload

$ systemctl restart docker

# 下面可以不需要,苹果系统可能需要。确保从cgroups均在同一个从groupfs

# cgroups是control groups的简称,它为Linux内核提供了一种任务聚集和划分的机制,通过一组参数集合将一些任务组织成一个或多个子系统。

# cgroups是实现IaaS虚拟化(kvm、lxc等),PaaS容器沙箱(Docker等)的资源管理控制部分的底层基础。

# 子系统是根据cgroup对任务的划分功能将任务按照一种指定的属性划分成的一个组,主要用来实现资源的控制。

# 在cgroup中,划分成的任务组以层次结构的形式组织,多个子系统形成一个数据结构中类似多根树的结构。cgroup包含了多个孤立的子系统,每一个子系统代表单一的资源

$ cat << EOF > /etc/docker/daemon.json

{

"exec-opts": ["native.cgroupdriver=cgroupfs"]

}

EOF

3、安装kubeadm,kubelet和kubectl

# 添加阿里云YUM软件源

cat > /etc/yum.repos.d/kubernetes.repo <<EOF

[kubernetes]

name=Kubernetes

baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64

enabled=1

gpgcheck=0

repo_gpgcheck=0

gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg

http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg

EOF

# baseurl:Kubernetes源设为阿里

# gpgcheck=0 表示对从这个源下载的rpm包不进行校验

# repo_gpgcheck 某些安全性配置文件会在 /etc/yum.conf 内全面启用,以便能检验软件库的中继数据的加密签署:1 表示会进行校验,就会报错,所以这里设为0

# 安装 kube* 三个组件

$ yum install -y kubelet-1.19.0 kubeadm-1.19.0 kubectl-1.19.0

$ systemctl enable kubelet # 开机启动

最终要三个命令都有:kube*

$ kubeadm reset # 出错后,重置,要全部卸载掉K8s,然后再install

$ journalctl -xefu kubelet # 查看启动日志

$ journalctl -u kubelet

Q:file /usr/bin/kubectl from install of kubectl-1.19.0-0.x86_64 conflicts with file from package kubernetes-client-1.5.2-0.7.git269f928.el7.x86_64

A:之前安装过低版本的kubeadm,yum移除即可

$ kubernetes-client-1.5.2-0.7.git269f928.el7.x86_64

Q:Loaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled; vendor preset: disabled)

A:可能/etc/docker/daemon.json 文件有误,不需要配置cgroup。还是启动不起来,看看虚拟机的配置,需要2C2G

Q:failed to load Kubelet config file /var/lib/kubelet/config.yaml

A:

# 都不启动

# master服务此时无法启动,因为没有配置文件 /var/lib/kubelet/config.yaml ,这个文件在 kubeadm init 的[kubelet-start]这一步写进来的。且写完后kubeadm帮启动了,无需自己启。

# node节点也无法启动,查看日志也是没有配置文件 /var/lib/kubelet/config.yaml ,这个文件在 kubeadm join 的[kubelet-start]这一步写进来的。

$ systemctl start kubelet

4、部署K8s master

# 组件清单

master:kube-apiserver、scheduler、controlelr-manager、etcd

node:kubelet、kube-proxy

kubeadm采用容器化的方式部署k8s组件,而不是用二进制源码的方式部署。

其中kubelet采用非容器化的,其他组件都是采用容器化方式部署的。

# 安装etcd

$ yum install etcd

# 下载镜像,kubeadm init的准备

$ vim mast.sh

#!/bin/bash

images=(

kube-apiserver:v1.19.0

kube-proxy:v1.19.0

kube-controller-manager:v1.19.0

kube-scheduler:v1.19.0

coredns:1.7.0

etcd:3.4.9-1

pause:3.2

)

for imageName in ${images[@]}; do

docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName

done

$ chmod 777 mast.sh

$ sh mast.sh

# 相当于批量执行,连不上多连几次

$ docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.19.0

$ docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.4.9-1

# 部署k8s master,仅在master节点执行即可

$ kubeadm init \

--apiserver-advertise-address=192.168.43.23 \

--image-repository registry.cn-hangzhou.aliyuncs.com/google_containers \

--kubernetes-version v1.19.0 \

--service-cidr=10.96.0.0/16 \

--pod-network-cidr=10.244.0.0/16 \

--ignore-preflight-errors=all

--apiserver-advertise-address 集群通告地址

--image-repository 由于默认拉取镜像地址k8s.gcr.io国内无法访问,这里指定阿里云镜像仓库地址

--kubernetes-version 指定k8s版本

--service-cidr service网段,集群内部虚拟网络

--pod-network-cidr Pod网段,与下面部署的CNI网络组件yaml中保持一致

# init初始化的日志解析

[preflight] ... 环境校验,拉取镜像 kubeadm config images pull

[certs]... 生成k8s证书和etcd证书,证书目录 /etc/kubernets/pki

[kubeconfig]... 生成kubeconfig文件,配置了apiserver的地址,kube-proxy要连接server的身份等。

[kubelet-start]... 写配置文件 /var/lib/kubelet/config.yaml;启动kubelet,不需要人为启动。

[control-plane]... 部署管理节点组件,用镜像启动容器。即安装这些组件:kube-apiserver、scheduler、controlelr-manager、etcd

[etcd]... 部署etcd数据库,用镜像启动容器。

[upload-config],[kubelet],[upload-certs]... 上传配置文件,kubelet配置信息,上传证书等,存储到k8s中。其他节点node配置集群时,会拉取这个配置文件,然后在本地生成去启动。

[mark-control-plane]... 给管理节点添加一个标签,kubectl get node,即可看到master的role角色为master。再添加一个污点,后面用到。

[bootstrap-token]... 自动为kubelet办法证书

[addons]... 部署插件,CoreDNS、kube-proxy

# 将连接集群的配置文件,拷贝到默认路径下。便于使用命令行工具 kubectl 直接管理集群。

$ mkdir -p $HOME/.kube

$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

$ sudo chown $(id -u):$(id -g) $HOME/.kube/config

# 提前保存令牌,用于在node执行

kubeadm join 192.168.43.23:6443 --token el5q0h.ol84kidb0fhlusp9 \

--discovery-token-ca-cert-hash sha256:dae5c056947982c4e5463a4e450786ab248e88e91ee45b2a7bf8dba44dad22e2

Q:[kubelet-check] The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get "http://localhost:10248/healthz": dial tcp [::1]:10248: connect: connection refused.

A:看上面的日志,因为没有禁止swap分区。禁止分区后,重启 systemctl restart kubelet,然后再次执行$ kubeadm init ...

如果init失败无法解决,可以执行$ kubeadmin reset,则k8的环境会清除掉,从头再来。

$ kubeadmin reset

$ journalctl -u kubelet # 查看kubelet日志

# 部署网络插件

$ wget https://docs.projectcalico.org/manifests/calico.yaml --no-check-certificate

# 先下载下来,然后修改IPV4的网段,修改这两行:

- name: CALICO_IPV4POOL_CIDR

value: "10.244.0.0/16"

$ kubectl apply -f calico.yaml # 然后部署插件

# 验证,再 kubectl get nodes,STATUS状态变成了Ready

$ kubectl get nodes

# 如果calicio状态不是running,则尝试手动拉取镜像

$ cat calico.yaml | grep image

$ grep image calico.yaml

$ docker pull calico/cni:v3.15.1

5、部署K8s node

1)用init时提前保存的令牌,执行 kubeadm join

# 在各个需要加入master的node执行:(在init的 日志中,后面join的时候会用到)

$ kubeadm join 192.168.43.23:6443 --token el5q0h.ol84kidb0fhlusp9 \

--discovery-token-ca-cert-hash sha256:dae5c056947982c4e5463a4e450786ab248e88e91ee45b2a7bf8dba44dad22e2

# join日志解析:

[preflight]... 基础校验,读取集群的配置信息

[kubelet-start] ... 读取kubelet配置信息并写到 "/var/lib/kubelet/config.yaml";读取环境信息并写到"/var/lib/kubelet/kubeadm-flags.env";启动 kubelet

执行报错:

Q: [ERROR Swap]: running with swap on is not supported. Please disable swap

A:禁止分区

Q:[ERROR FileContent--proc-sys-net-ipv4-ip_forward]: /proc/sys/net/ipv4/ip_forward contents are not set to 1

出现这个问题的原因是想kubernetes node节点想加入主节点,然后 /proc/sys/net/ipv4/ip_forward 文件没有设置成1

A:执行命令 $ sysctl -w net.ipv4.ip_forward=1

Q:error execution phase preflight: couldn't validate the identity of the API Server: could not find a JWS signature in the cluster-info ConfigMap for token ID "el5q0h"

A:创建新的令牌,重新join

#如果超过2小时忘记了令牌,可以这样做

$ kubeadm token create --print-join-command #新令牌

$ kubeadm token create --ttl 0 --print-join-command #永不过期的令牌

kubeadm join 192.168.43.23:6443 --token w2hiyq.429yixajmuvfvcnk --discovery-token-ca-cert-hash sha256:dae5c056947982c4e5463a4e450786ab248e88e91ee45b2a7bf8dba44dad22e2

# master执行,查看是否加入成功

$ kubectl get node

$ kubectl get pods -n kube-system

Q:出现:Unable to connect to the server: net/http: TLS handshake timeout 问题

A:这些问题的出现都由可能是自己的master内存太小。关闭交换分区后内存更紧张。

$ systemctl status kubelet # 查看是否启动成功

$ kubelet --version # 查看kubelet版本 Kubernetes v1.21.2

6、部署dashboard

$ wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.3/aio/deploy/recommended.yaml

下载不了,则尝试到github上手动下载下来,地址:https://codechina.csdn.net/mirrors/kubernetes/kubernetes/-/tree/release-1.19

找到对应kubelet的版本1.19,然后一步步进入文件夹找到文件:cluster/addons/dashboard/dashboard.yaml

下载后,重命名为dashboard.yaml,修改如下:

kind: Service

apiVersion: v1

metadata:

labels:

k8s-app: kubernetes-dashboard

kubernetes.io/cluster-service: "true"

addonmanager.kubernetes.io/mode: Reconcile

name: kubernetes-dashboard

namespace: kubernetes-dashboard

spec:

ports:

- port: 443

targetPort: 8443

nodePort: 30001

selector:

k8s-app: kubernetes-dashboard

type: NodePort

$ kubectl apply -f dashboard.yaml

# 然后查看状态,一直是ContainerCreating,在拉镜像等,需要等待,直到变成Running。

$ kubectl get pods -n kubernetes-dashboard

# 加上svc,查看端口等

$ kubectl get pods,svc -n kubernetes-dashboard

Q:发现端口没有NodePort

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

service/dashboard-metrics-scraper ClusterIP 10.96.27.22 <none> 8000/TCP 8m1s

A:查看上面加的type: NodePort,必须与selector对齐。

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

service/dashboard-metrics-scraper ClusterIP 10.96.27.22 <none> 8000/TCP 11m

service/kubernetes-dashboard NodePort 10.96.7.197 <none> 443:30001/TCP 14s

对内集群暴露的端口是443,对外用户暴露使用的是30001

然后浏览器访问 https://192.168.43.23:30001/

点击高级,复制token进来。token生成如下:

# kube-system命名空间下创建dashboard-admin用户

$ kubectl create serviceaccount dashboard-admin -n kube-system

# 用户授权 ,管理员角色clusterrolebinding,如果先授权了其他角色,无需改token,直接create此管理员角色即可。

$ kubectl create clusterrolebinding dashboard-admin -n kube-system --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin

# 获取用户token,先找到secret的name,为:dashboard-admin-token-58xmr

$ kubectl get secret -n kube-system

# 获取token,浏览器已经有其他token,则清除Cookie等数据即可

$ kubectl describe secret dashboard-admin-token-58xmr -n kube-system

eyJhbGciOiJSUzI1NiIsImtpZCI6Inh5T0otTVdNT2tRM0pJOHF1QkRCdHdpaHdZc21VXzRxeVRjUDlieHVZYnMifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkYXNoYm9hcmQtYWRtaW4tdG9rZW4tNTh4bXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGFzaGJvYXJkLWFkbWluIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiNzI4MmY0MjYtMjFjNy00MGEyLThmMDgtNWI3Njc4NTE5ZjM0Iiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmUtc3lzdGVtOmRhc2hib2FyZC1hZG1pbiJ9.KaBfuAmbcsrogqEy--rIBH5ZNKAsPyWr8kgX59OhXfUCGYKNWhDLMy1UZX2LfItCGw5BwcVy6PSoDgyc16q8WlUivzb3EpV-nxuA77yOhbsHFkmVhMlMtI-TtieVJZPU6FMyea6zNmAgRwCVy9HTdS7jjNtKPlkF0pTQhiz264lw54JRhfxJxvZ3Gx4FoCG5O3nPDuwgP7URkGLt3Zl2JYlYZtnuXl05wQOL3fHTvrEtnF3c2ABCNMnX3kuYQQiA-hZt7VXIZalrTUuTfnZaMLp1K5J0AT5se1-eTlYnOPECctukfFihlDNMptpNiUD6q45ZZbvw60eKH5ZkmGjoQA

7、制作镜像

7.1、命令行方式制作镜像

1)创建/删除deployment控制器,部署镜像

# master中,创建一个deployment名为web,镜像为nginx,副本数为3

$ kubectl create deployment web --image=nginx --replicas=3

# 会出现三个web,状态从ContainerCreating变为Running时才可用

$ kubectl get pods

NAME READY STATUS RESTARTS AGE

web-96d5df5c8-kbjk4 0/1 ContainerCreating 0 36s

web-96d5df5c8-st9pk 0/1 ContainerCreating 0 36s

web-96d5df5c8-v9zjs 0/1 ContainerCreating 0 36s

$ kubectl get deployment

NAME READY UP-TO-DATE AVAILABLE AGE

web 1/3 3 1 87s

$ kubectl delete deployment web

$ kubectl get deploy,pods

2)暴露/删除service,将pod暴露出去

# --port k8s内部的端口,要指定;--target-port=80 对外暴露的端口,如Nginx默认是80,Tomcat是8080;类型,

$ kubectl expose deployment web --port=80 --target-port=80 --type=NodePort

$ kubectl get pods

# 查看暴露的服务,80是k8s内部端口,32137是对外暴露的端口,浏览器中访问

$ kubectl get service

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 19h

web NodePort 10.96.165.23 <none> 80:32137/TCP 90s

3)浏览器访问应用

# 端口随机生成,通过get svc获取

http://NodeIp:Port

如:http://192.168.43.25:32137

# 浏览器访问后,可通过日志,查询三个web是访问的哪一个

$ kubectl logs web-96d5df5c8-kbjk4

192.168.43.25 - - [04/Nov/2021:06:30:10 +0000] "GET / HTTP/1.1" 200 615 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0" "-"

192.168.43.25 - - [04/Nov/2021:06:30:10 +0000] "GET /favicon.ico HTTP/1.1" 404 153 "http://192.168.43.25:32137/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0" "-"

7.2、YAML文件方式制作镜像

K8s时一个容器编排引擎,使用YAML文件编排部署应用

使用yaml文件创建Deployment,等同于 $ kubectl create deployment web --image=nginx --replicas=3

官网https://kubernetes.io/docs/home/,搜索deployment,进入第一个 https://kubernetes.io/zh/docs/concepts/workloads/controllers/deployment/,找到示例

使用yaml文件创建service,等同于 $ kubectl expose deployment web --port=80 --target-port=80 --type=NodePort

官网https://kubernetes.io/docs/home/,搜索service,找到样例

$ vim web.yaml

====web.yaml开始===============

apiVersion: apps/v1 # apiVersion:api的版本,可以通过命令获取 $ kubectl api-resources | grep deployment

kind: Deployment # 创建Deployment。资源的类型,k8s中的类型大概有70多种,常用的十几个

metadata: # 资源元数据

name: web

namespace: ms # 命名空间

spec: # 资源规格

replicas: 3 # 副本数

selector: # 标签选择器,与下面的metadata.labels保持一致

matchLabels:

app: nginx # 每一个资源都是唯一的

template: # Pod模板,template是被控制对象,上面是控制器的定义

metadata: # Pod元数据

labels:

app: nginx

spec: # Pod规格

containers: # 容器配置

- name: nginx

image: nginx:1.16 # 指定镜像,可指定版本,下次升级的时候,可以对版本升级,如:nginx:1.16,nginx:1.17

---

apiVersion: v1

kind: Service # 创建Service

metadata:

name: web

namespace: ms # 命名空间

spec:

selector: # 标签选择器

app: nginx # app要与Deployment中标签保持一致

ports:

- protocol: TCP

port: 8888 # Service端口,通过ClusterIP访问用

targetPort: 80 # 容器端口。镜像内服务端口,例如Nginx镜像是80

nodePort: 31001 # nodePort用于type为NodePort时,不指定则随机获取,值范围:30000~32767

type: NodePort # Service类型为NodePort,可以在集群外部访问。如浏览器访问<任意Node的ip>:<NodePort>。不指定则用默认的类型:clusterIp。

====web.yaml结束===============

# 创建命名空间

$ kubectl create namespace ms

$ kubectl apply -f web.yaml

deployment.apps/web created

service/web created

# 验证,pod状态都是running时,才可用

$ kubectl get pods,service -n ms

NAME READY STATUS RESTARTS AGE

pod/web-6d4cf56db6-4v4zk 0/1 ContainerCreating 0 2m26s

pod/web-6d4cf56db6-97zll 1/1 Running 0 2m26s

pod/web-6d4cf56db6-kz2bp 1/1 Running 0 2m26s

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

service/web NodePort 10.96.100.143 <none> 8888:31001/TCP 2m26s

# 查看service关联的pod容器ip地址,浏览器访问端口,实际是分配到endpoints里面的一个去执行

$ kubectl get endpoints -n ms

# 浏览器访问,查看网络中的响应头,nginx/1.16.1

http://192.168.43.25:30996

# 查看pod容器的日志

$ kubectl logs web-96d5df5c8-kbjk4

8、发布升级

8.1、yaml文件方式升级

# 下面完成升级操作,架构nginx:1.16升级到1.17,先修改yaml文件里nginx的版本,再apply

$ vim yamls/web.yaml

$ kubectl apply -f yamls/web.yaml --record=true

# 等待状态都是running,即滚动升级完成,再访问浏览器,F5清除缓存,版本为1.17,升级成功

Server: nginx/1.17.10

# 查看升级步骤

$ kubectl describe deployment web -n ms

...

NewReplicaSet: web-db749865c (3/3 replicas created)

Events:

Type Reason Age From Message

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

Normal ScalingReplicaSet 22m deployment-controller Scaled up replica set web-6d4cf56db6 to 3

Normal ScalingReplicaSet 13m deployment-controller Scaled up replica set web-db749865c to 1

Normal ScalingReplicaSet 10m deployment-controller Scaled down replica set web-6d4cf56db6 to 2

Normal ScalingReplicaSet 10m deployment-controller Scaled up replica set web-db749865c to 2

Normal ScalingReplicaSet 10m deployment-controller Scaled down replica set web-6d4cf56db6 to 1

Normal ScalingReplicaSet 10m deployment-controller Scaled up replica set web-db749865c to 3

Normal ScalingReplicaSet 10m deployment-controller Scaled down replica set web-6d4cf56db6 to 0

# 上述日志可看到,web的三个pod,滚动升级

Q:浏览器http://192.168.43.25:31354,不通时,查看日志也没有

A:查看service关联的pod,发现web2没有endpoint,可能是web2的deployment和service创建有问题

$ kubectl delete deployment web2

$ kubectl get deployments

$ kubectl delete service web2

$ kubectl get pod,service

8.2、命令行方式升级

# 容器名称:即containers下面的-name: nginx

# kubectl set image deployment web <容器名称>=<镜像名称>

$ kubectl set image deployment web nginx=nginx:1.18 -n ms --record=true

# 等到running后,浏览器验证

8.3、失败回滚

发布应用失败回滚(项目升级失败,恢复到正常版本)

# 查看发布版本的历史记录,发布的三次记录。但是CHANGE-CAUSE为none,在apply时,后面加上record即可:$ kubectl apply -f web.yaml --record=true

# 使用免交互的升级方式,加上record,更能看出发布升级日志:$ kubectl set image deployment web nginx=nginx:1.18 -n ms --record=true

$ kubectl rollout history deployment/web -n ms

deployment.apps/web

REVISION CHANGE-CAUSE

1 <none>

2 <none>

3 <none>

# 回滚到上一个版本。查看浏览器,回滚到了1.17

$ kubectl rollout undo deployment/web

# 回滚到指定版本。通过免交互方式--record,可以知道某一个版本发布了什么。

$ kubectl rollout undo deployment/web to --to-verision=2

9、水平扩容、缩容

9.1、yaml方式

修改yaml中的replicas值,再apply -f

9.2、命令行方式

$ kubectl scale deployment web --replicas=6 -n ms

$ kubectl get pods,service -n ms # 验证

10、应用下线

$ kubectl delete deployment web -n ms

$ kubectl delete service web -n ms

$ kubectl delete -f yamls/web.yaml # 删除yaml文件中所有的deployment和service

$ kubectl delete pod ... # 删除pod后,deployment控制器会发现没有了,又会再次生成pod。所以直接删除pod没有用。

11、使用控制器部署Docker镜像

构建Docker镜像,见Docker中构建镜像

$ vim xxl-admin.yaml

apiVersion: apps/v1 # apiVersion:api的版本,可以通过命令获取 $ kubectl api-resources | grep deployment

kind: Deployment # 创建Deployment。资源的类型,k8s中的类型大概有70多种,常用的十几个

metadata: # 资源元数据

name: xxl-admin

spec: # 资源规格

replicas: 3 # 副本数

selector: # 标签选择器,与下面的metadata.labels保持一致

matchLabels:

app: xxl-admin # 每一个资源都是唯一的

template: # Pod模板,template是被控制对象,上面是控制器的定义

metadata: # Pod元数据

labels:

app: xxl-admin

spec: # Pod规格

containers: # 容器配置

- image: chenchg/xxl-admin # 指定镜像,可指定版本,下次升级的时候,可以对版本升级,如:nginx:1.16,nginx:1.17

name: xxl-admin

---

apiVersion: v1

kind: Service # 创建Service

metadata:

name: xxl-admin

spec:

selector: # 标签选择器

app: xxl-admin # app要与Deployment中标签保持一致

ports:

- protocol: TCP

port: 8888 # Service端口,通过ClusterIP访问用

targetPort: 9091 # 容器端口。镜像内服务端口,例如Nginx镜像是80

nodePort: 31001 # nodePort用于type为NodePort时,不指定则随机获取,值范围:30000~32767

type: NodePort # Service类型为NodePort,可以在集群外部访问。如浏览器访问<任意Node的ip>:<NodePort>。不指定则用默认的类型:clusterIp。

$ kubectl apply -f xxl-admin.yaml

Q:that the pod didn't tolerate, 2 node(s) had taint {node.kubernetes.io/unreachable: }, that the pod didn't tolerate.

A:node.kubernetes.io/unreachable,可能node节点已经不可用了,状态是NotReady

当某种条件为真时,节点控制器会自动给节点添加一个污点。当前内置的污点包括:

node.kubernetes.io/not-ready:节点未准备好。这相当于节点状态 Ready 的值为 "False"。

node.kubernetes.io/unreachable:节点控制器访问不到节点. 这相当于节点状态 Ready 的值为 "Unknown"。

node.kubernetes.io/memory-pressure:节点存在内存压力。

node.kubernetes.io/disk-pressure:节点存在磁盘压力。

node.kubernetes.io/pid-pressure: 节点的 PID 压力。

node.kubernetes.io/network-unavailable:节点网络不可用。

node.kubernetes.io/unschedulable: 节点不可调度。

node.cloudprovider.kubernetes.io/uninitialized:如果 kubelet 启动时指定了一个 "外部" 云平台驱动, 它将给当前节点添加一个污点将其标志为不可用。在 cloud-controller-manager 的一个控制器初始化这个节点后,kubelet 将删除这个污点。

$ kubectl get pod,svc

12、卸载K8s

$ kubeadm reset -f
$ modprobe -r ipip
$ lsmod
$ rm -rf ~/.kube/
$ rm -rf /etc/kubernetes/
$ rm -rf /etc/systemd/system/kubelet.service.d
$ rm -rf /etc/systemd/system/kubelet.service
$ rm -rf /usr/bin/kube*
$ rm -rf /etc/cni
$ rm -rf /opt/cni
$ yum clean all
$ yum remove kube*

$ rm -rf $HOME/.kube

# 如果卸载重装k8s,etcd可不卸载
$ rm -rf /var/lib/etcd    # 不卸载etcd
$ rm -rf /var/etcd    # 不卸载etcd

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐