kubernetes基础
kubernetes介绍
Kubernetes是Google在2014年开源的一款容器集群系统,简称k8s
Kubernetes用于容器化应用程序部署、扩展和管理,目标是让容器化应用简单高效
官方网站:https://kubernetes.io/
官方文档:https://kubernetes.io/zh/docs/home/
K8S是一组服务器的集群,对节点(node)上的容器进行管理。
主要提供了如下的主要功能:
1.自我修复:一旦某-个容器崩溃,能够在1秒中左右迅速启动新的容器
2.弹性伸缩:可以根据需要,自动对集群中正在运行的容器数量进行调整
3.服务发现:服务可以通过自动发现的形式找到它所依赖的服务
4.负载均衡:如果一个服务起动了多个容器,能够自动实现请求的负载均衡
5.版本回退:如果发现新发布的程序版本有问题,可以立即回退到原来的版本
6.存储编排:可以根据容器自身的需求自动创建存储卷
NODE1节点NODE2节点REDIS2容器NGINX2容器NGINX1容器REDIS1容器NODE4节点NODE3节点MYSQL2容器MYSQL1容器NGINX2容器NGINX1容器
1.自我修复:一旦某-个容器崩溃,能够在1秒中左右迅速启动新的容器,在k8s集群中
如果某个容器宕机了,会迅速启动一台新的nginx容器。
2.弹性伸缩:在k8s集群中有4台nginx容器,总共抗并发4000 如果突然并发量堆积6000-8000 迅速在k8s集群中 扩容容器 如果流量下降之后就会对我们的容器缩容
3.负载均衡:在k8s集群中 有n多个容器组成集群 通过负载均衡策略来实现访问
4.版本回退:如果发现新发布的程序版本有问题,可以立即回退到原来的版本 灰度发布
k8s 分成Master 负责整个k8s集群管理 node节点(工作)运行nginx
节点—服务器
kubernetes 组件
kubernetes集群主要由控制节点(Master)、工作节点(Node)组成
Master组件
集群的控制平面,集群的决策 负责管理k8s 集群管理
apiserver
Kubernetes API:集群统一入口,各个组件的协调者,以RESTful API提供接口服务,所有对象资源的增删改查和监听操作都交给apiserver处理后再提交etcd存储
控制集群入口
scheduler
负责资源调度,按照预定的调度策略将Pod调度到相应Node上
例如 集群运行一个nginx容器,通过scheduler 根据调度策略计算 nginx 安装到那台对应的工作节点上(计算);
controller-manager
处理集群中常规的后台任务,一个资源对应一个控制器,而controller-manager就是负责管理这些控制器的
维护集群的状态。比如故障检测、自动扩展、滚动更新等
例如 集群运行一个nginx容器,通过scheduler 根据调度策略计算 nginx 安装到那台对应的工作节点上(计算),在 通过controller-manager 安排 将nginx安装到对应的工作节点上(安排)。
etcd
分布式键值存储系统。用于保存集群状态数据,比如Pod。Service等对象信息
我们可以将etcd 改成mysql。
node组件
集群的数据平面,负责为容器提供运行环境(工作节点)
kubelet
kubelet是Master在Node节点上的Agent,管理本机运行容器的生命周期。比如创建容器、Pod挂载数据卷、下载secret、获取容器和节点状态等工作。kubelet将每个Pod转换成一组容器
kubelet 发送命令给docker 来运行容器
kube-proxy
在Node节点或实现Pod网络代理,维护网络规则和四层负载均衡工作
访问程序的入口
docker
运行nginx 计算
访问nginx
容器引擎:运行容器
例如通过k8s运行一个nginx:
1.首先发送请求到Master节点(控制节点) ApiServer组件
2.ApiServer组件会根据scheduler组件计算出 nginx 应该安装到具体那台工作节点上
3.ApiServer组件在调用controller-manager组件,通知node节点安装该nginx服务
4.Node节点中的kubelet接受到控制节点的通知,使用docker运行一个nginx容器(nginx pod)
pod是k8s最小操作单元 一个pod可以运行多个容器
5.nginx运行成功之后,在通过kube-proxy 来对我们的pod进行访问。
kubectl create deployment nginx --image=nginx:1.14-alpine
常见名词
1.Master:集群控制节点,每个集群需要至少一个master节 点负责集群的管控
2.Node:工作负载节点,由master分配容器到这些node工作节点上,然后node节点上的docker负责容器的运行
3.Pod: kubernetes的最小控制单元,容器都是运行在pod中的,-个pod中可以有1个或者多个容器
4.Controller:控制器,通过它来实现对pod的管理,比如启动pod、 停止pod、伸缩pod的数量等等
5.Service: pod对外服务的统一入口,下面可以维护者同一类的多个pod
6.Label:标签,用于对pod进行分类,同一类pod会拥有相同的标签
7.NameSpace:命名空间,用来隔离pod的运行环境
kubernetes 环境搭建
1.一主多从: 在学习阶段我们只需要一台Master节点和多台Node节点,搭建简单,有单机发生故障风险,适合用于测试环境
2.多主多从:多台Master节点和多台Node节点,搭建有一些麻烦,安全系数高,适合用于生产环境
环境说明
1.基于云服务器构建kubernetes 环境
2.本地通过虚拟机构建kubernetes 环境
安装Centos7.6 准备一个干净的,让后直接克隆三台虚拟机即可
启动虚拟机过程 ,建议分开的形式启动这三台虚拟机
192.168.75.136----干净-VMWARE WORKSTATION文件(F) 查看(V) 虚拟机(M)选项卡(T)帮助(H)库192.168.75.136—干净X在此处键入内容进行搜索1192.168.75.136—干净我的电脑唱192.168.75.136—干净开启此虚拟机画192.168.75.139编辑虚拟机设置画192.168.75.140画192.168.75.141设备画192.168.75.143内存2GB画 192.168.75.142处理器鱼共享虚拟机硬盘(SCSI)20 GBCD/DVD(IDE)正在使用文件D:…网络适配器NAT存在USB控制器声卡自动检测打印机存在显示器自动检测描述在此处键入对该虚拟机的描述.
注意:克隆了之后 记得一定要修改该linux服务器 mac地址
在D:\path\linux 创建 三个不同的文件夹
新建打开选择组织此电脑本地磁盘(D:)PATHLINUX类型修改日期名称大小文件夹012022/2/17 16:32文件夹022022/2/17 16:32文件夹032022/2/17 16:32
克隆三台服务器
克隆成功之后,重置每台的mac地址
集群搭建方式
1.kubeadm
kubeadm是一个工具,提供kubeadm init 和kubeadm join,用于快速部署Kubernetes集群
下载地址:https://kubernetes.io/docs/reference/setup-tools/kubeadm/
2.二进制 从官方下载发行版的二进制包,手动部署每个组件,组成Kubernetes集群
下载地址:https://github.com/kubernetes/kubernetes/releases
3.minikube 一个用于快速搭建单节点kubernetes的工具
下载地址:https://minikube.sigs.k8s.io/docs/start/
环境准备
1.一个主多个工作节点: 一台Master节点和多台Node节点,搭建简单,但是有单机故障风险,适合用于测试环境
2.多主节点多工作节点:多台Master节点和多台Node节点,搭建麻烦,安全性高,适合用于生产环境程序员练习,采用一主多从即可
ip地址 | 类型 | 操作系统 | 服务配置 |
---|---|---|---|
192.168.75.163 | Master | Centos7.6 | 2核CPU 2G内存 20G硬盘 |
192.168.75.164 | Node1 | Centos7.6 | 2核CPU 2G内存 20G硬盘 |
192.168.75.165 | Node2 | Centos7.6 | 2核CPU 2G内存 20G硬盘 |
使用 XshellPortable.exe 远程连接到这三台服务器
初始化环境
需要在这三台服务器上执行以下操作:
1.检查操作系统的版本
#此方式下安装kubernetes集群要求Centos版本要在7.5或之上
cat /etc/redhat-release
2.主机名解析
为了方便后面集群节点间的直接调用,在这配置一下主机名解析, 企业中推荐使用内部DNS服务器
#主机名成解析编辑三台服务器的/etc/hosts文件,添加下面内容
vi /etc/hosts
192.168.75.173 master
192.168.75.167 node1
192.168.75.175 node2
让后节点之间相互ping下
ping master
ping node1
ping node2
3.时间同步
kubernetes要求集群中的节点时间必须精确一致, 这里直接使用chronyd服务从网络同步时间。
企业中建议配置内部的时间同步服务器
yum install -y chrony
systemctl start chronyd
systemctl enable chronyd
4.禁用iptables和firewalld服务
kubernetes和docker在运行中会产生大量的iptables规则,为了不让系统规则跟它们混淆,直接关闭系统的规则
# 1关闭firewalld服务
[root@master ~]# systemctl stop firewalld
[root@master ~]# systemctl disable firewalld
# 2关闭iptables服务
[root@master ~]# systemctl disabled iptables
[root@master ~]# systemctl disable iptables
5.关闭selinux
selinux是linux系统下的一个安全服务,如果不关闭它,在安装集群中会产生各种各样的奇葩问题
vi /etc/selinux/config 文件,修改SELINUX的值为disabled
#注意修改完毕之后需要重启 linux服务
SELINUX=disabled
改成:
6.禁用swap分区
swap分区指的是虚拟内存分区,它的作用是在物理内存使用完之后,将磁盘空间虚拟成内存来使用
启用swap设备会对系统的性能产生非常负面的影响,因此kubernetes要求每个节点都要禁用swap设备
但是如果因为某些原因确实不能关闭swap分区,就需要在集群安装过程中通过明确的参数进行配置说明
#编辑分区配置文件/etc/fstab,注释掉swap分区一行
vi /etc/fstab
7.修改Linux内核参数
#修改linux的内核参数,添加网桥过滤和地址转发功能
vi /etc/sysctl.d/kubernetes.conf文件,添加如下配置:
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
#重新加载配置
[root@mayikt ~]# sysctl -p
#加载网桥过滤模块
[root@mayikt ~]# modprobe br_netfilter
#查看网桥过滤模块是否加载成功
[root@mayikt ~]# lsmod | grep br_netfilter
8.配置ipvs功能
在kubernetes中service有两种代理模型,-种是基于iptables的, - -种是基于ipvs的
两者比较的话,ipvs的性能明显要高一些,但是如果要使用它,需要手动载入ipvs模块
k8s service 会使用 ipvs/iptables
# 1安装ipset和ipvsadm
[root@mayikt ~]# yum install ipset ipvsadmin -y
# 2添加需要加载的模块写入脚本文件
[ root@mayikt ~]# cat <<EOF > /etc/sysconfig/modules/ipvs.modules
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF
# 3为脚本文件添加执行权限
[root@mayikt ~]# chmod +x /etc/sysconfig/modules/ipvs.modules
# 4执行脚本文件
[root@mayikt ~]# sh +x /etc/sysconfig/modules/ipvs.modules
# 5查看对应的模块是否加载成功
[root@mayikt ~]# lsmod | grep -e ip_vs -e nf_conntrack_ipv4
9.重启Linux系统
reboot
安装kubernetes组件
安装docker
# 1切换镜像源
[root@master ~]# wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
如果报错 -bash: wget: 未找到命令
则执行: yum -y install wget
# 2查看当前镜像源中支持的docker版本
[root@master ~]# yum list docker-ce --showduplicates
# 3安装特定版本的docker-ce
#指定--setopt=obsoletes=0,否则yum会自动安装更高版本
[root@master ~]# yum install --setopt=obsoletes=0 docker-ce-18.06.3.ce-3.el7 -y
# 4添加一个配置文件 阿里云加速镜像
[root@master ~]# mkdir /etc/docker
[ root@master ~]# cat <<EOF > /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"registry-mirrors": [ "https://66mzqrih.mirror.aliyuncs.com"]
}
EOF
# 5启动docker
[root@master ~]# systemctl start docker
[root@master ~]# systemctl enable docker
# 6检查docker状态和版本
[root@master ~]# docker --version
安装kubernetes组件
#1.由于kubernetes的镜像源在国外,速度比较慢,这里切换成国内的镜像源
#2.vi /etc/yum.repos.d/kubernetes.repo,添加下面的配置
[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
#3.安装kubeadm、kubelet和kubectl
[root@master ~]# yum install --setopt=obsoletes=0 kubeadm-1.17.4-0 kubelet-1.17.4-0 kubectl-1.17.4-0 -y
#4.配置kubelet的cgroup
#5.vi /etc/sysconfig/kubelet,添加下面的配置
KUBELET_CGROUP_ARGS="--cgroup-driver=systemd"
KUBE_PROXY_MODE="ipvs"
#6.设置kubelet开机自启
[root@master ~]# systemctl enable kubelet
准备集群镜像
在阿里云仓库中存在该镜像 在更改为k8s 官方的名称,同时需要在所有节点操作
#在安装k8s集群之前,必须要提前准备好集群需要的镜像,所需镜像可以通过下面命令查看
1.kubeadm config images list
k8s.gcr.io/kube-apiserver:v1.17.17
k8s.gcr.io/kube-controller-manager:v1.17.17
k8s.gcr.io/kube-scheduler:v1.17.17
k8s.gcr.io/kube-proxy:v1.17.17
k8s.gcr.io/pause:3.1
k8s.gcr.io/etcd:3.4.3-0
k8s.gcr.io/coredns:1.6.5
2.下载镜像
#此镜像在k8s的仓库中,由于网络原因,无法连接,下面提供了-种替代方案
images=(
kube-apiserver:v1.17.4
kube-controller-manager:v1.17.4
kube-scheduler:v1.17.4
kube-proxy:v1.17.4
pause:3.1
etcd:3.4.3-0
coredns:1.6.5
)
for imageName in ${images[@]} ; do
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName k8s.gcr.io/$imageName
docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
done
执行docker images
集群初始化
只需要在master节点上执行即可
kubeadm init \
--kubernetes-version=v1.17.4 \
--pod-network-cidr=10.244.0.0/16 \
--image-repository registry.aliyuncs.com/google_containers \
--service-cidr=10.96.0.0/12 \
--apiserver-advertise-address=192.168.75.173
注意:--image-repository 需要更改为阿里云加速镜像
--apiserver-advertise-address=192.168.75.152 修改为自己的 master的ip。
初始化大概需要花费1分钟左右
journalctl -xeu kubelet 查看日志
备份:
kubeadm join 192.168.75.166:6443 --token v66ych.elj3af6fyobz6du2 \
--discovery-token-ca-cert-hash sha256:7d9f8c69ce42ec8f25b24077e0ad202dd80606bdb4667342c147f098f2e038e8
2.创建必要文件
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
3.拷贝该到其他两个节点执行 加入 k8s集群环境
kubeadm join 192.168.75.166:6443 --token v66ych.elj3af6fyobz6du2 \
--discovery-token-ca-cert-hash sha256:7d9f8c69ce42ec8f25b24077e0ad202dd80606bdb4667342c147f098f2e038e8
4.执行 kubectl get nodes
网络插件的安装
kube-flannel.yml 上传到Master节点任意位置
修改文件中quay.io仓库为quay-mirror.qiniu.com
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: psp.flannel.unprivileged
annotations:
seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default
seccomp.security.alpha.kubernetes.io/defaultProfileName: docker/default
apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default
apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default
spec:
privileged: false
volumes:
- configMap
- secret
- emptyDir
- hostPath
allowedHostPaths:
- pathPrefix: "/etc/cni/net.d"
- pathPrefix: "/etc/kube-flannel"
- pathPrefix: "/run/flannel"
readOnlyRootFilesystem: false
# Users and groups
runAsUser:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
fsGroup:
rule: RunAsAny
# Privilege Escalation
allowPrivilegeEscalation: false
defaultAllowPrivilegeEscalation: false
# Capabilities
allowedCapabilities: ['NET_ADMIN']
defaultAddCapabilities: []
requiredDropCapabilities: []
# Host namespaces
hostPID: false
hostIPC: false
hostNetwork: true
hostPorts:
- min: 0
max: 65535
# SELinux
seLinux:
# SELinux is unsed in CaaSP
rule: 'RunAsAny'
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: flannel
rules:
- apiGroups: ['extensions']
resources: ['podsecuritypolicies']
verbs: ['use']
resourceNames: ['psp.flannel.unprivileged']
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- apiGroups:
- ""
resources:
- nodes
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- nodes/status
verbs:
- patch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: flannel
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: flannel
subjects:
- kind: ServiceAccount
name: flannel
namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: flannel
namespace: kube-system
---
kind: ConfigMap
apiVersion: v1
metadata:
name: kube-flannel-cfg
namespace: kube-system
labels:
tier: node
app: flannel
data:
cni-conf.json: |
{
"cniVersion": "0.2.0",
"name": "cbr0",
"plugins": [
{
"type": "flannel",
"delegate": {
"hairpinMode": true,
"isDefaultGateway": true
}
},
{
"type": "portmap",
"capabilities": {
"portMappings": true
}
}
]
}
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "vxlan"
}
}
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: kube-flannel-ds-amd64
namespace: kube-system
labels:
tier: node
app: flannel
spec:
selector:
matchLabels:
app: flannel
template:
metadata:
labels:
tier: node
app: flannel
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: beta.kubernetes.io/os
operator: In
values:
- linux
- key: beta.kubernetes.io/arch
operator: In
values:
- amd64
hostNetwork: true
tolerations:
- operator: Exists
effect: NoSchedule
serviceAccountName: flannel
initContainers:
- name: install-cni
image: quay-mirror.qiniu.com/coreos/flannel:v0.11.0-amd64
command:
- cp
args:
- -f
- /etc/kube-flannel/cni-conf.json
- /etc/cni/net.d/10-flannel.conflist
volumeMounts:
- name: cni
mountPath: /etc/cni/net.d
- name: flannel-cfg
mountPath: /etc/kube-flannel/
containers:
- name: kube-flannel
image: quay-mirror.qiniu.com/coreos/flannel:v0.11.0-amd64
command:
- /opt/bin/flanneld
args:
- --ip-masq
- --kube-subnet-mgr
resources:
requests:
cpu: "100m"
memory: "50Mi"
limits:
cpu: "100m"
memory: "50Mi"
securityContext:
privileged: false
capabilities:
add: ["NET_ADMIN"]
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
volumeMounts:
- name: run
mountPath: /run/flannel
- name: flannel-cfg
mountPath: /etc/kube-flannel/
volumes:
- name: run
hostPath:
path: /run/flannel
- name: cni
hostPath:
path: /etc/cni/net.d
- name: flannel-cfg
configMap:
name: kube-flannel-cfg
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: kube-flannel-ds-arm64
namespace: kube-system
labels:
tier: node
app: flannel
spec:
selector:
matchLabels:
app: flannel
template:
metadata:
labels:
tier: node
app: flannel
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: beta.kubernetes.io/os
operator: In
values:
- linux
- key: beta.kubernetes.io/arch
operator: In
values:
- arm64
hostNetwork: true
tolerations:
- operator: Exists
effect: NoSchedule
serviceAccountName: flannel
initContainers:
- name: install-cni
image: quay-mirror.qiniu.com/coreos/flannel:v0.11.0-arm64
command:
- cp
args:
- -f
- /etc/kube-flannel/cni-conf.json
- /etc/cni/net.d/10-flannel.conflist
volumeMounts:
- name: cni
mountPath: /etc/cni/net.d
- name: flannel-cfg
mountPath: /etc/kube-flannel/
containers:
- name: kube-flannel
image: quay-mirror.qiniu.com/coreos/flannel:v0.11.0-arm64
command:
- /opt/bin/flanneld
args:
- --ip-masq
- --kube-subnet-mgr
resources:
requests:
cpu: "100m"
memory: "50Mi"
limits:
cpu: "100m"
memory: "50Mi"
securityContext:
privileged: false
capabilities:
add: ["NET_ADMIN"]
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
volumeMounts:
- name: run
mountPath: /run/flannel
- name: flannel-cfg
mountPath: /etc/kube-flannel/
volumes:
- name: run
hostPath:
path: /run/flannel
- name: cni
hostPath:
path: /etc/cni/net.d
- name: flannel-cfg
configMap:
name: kube-flannel-cfg
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: kube-flannel-ds-arm
namespace: kube-system
labels:
tier: node
app: flannel
spec:
selector:
matchLabels:
app: flannel
template:
metadata:
labels:
tier: node
app: flannel
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: beta.kubernetes.io/os
operator: In
values:
- linux
- key: beta.kubernetes.io/arch
operator: In
values:
- arm
hostNetwork: true
tolerations:
- operator: Exists
effect: NoSchedule
serviceAccountName: flannel
initContainers:
- name: install-cni
image: quay-mirror.qiniu.com/coreos/flannel:v0.11.0-arm
command:
- cp
args:
- -f
- /etc/kube-flannel/cni-conf.json
- /etc/cni/net.d/10-flannel.conflist
volumeMounts:
- name: cni
mountPath: /etc/cni/net.d
- name: flannel-cfg
mountPath: /etc/kube-flannel/
containers:
- name: kube-flannel
image: quay-mirror.qiniu.com/coreos/flannel:v0.11.0-arm
command:
- /opt/bin/flanneld
args:
- --ip-masq
- --kube-subnet-mgr
resources:
requests:
cpu: "100m"
memory: "50Mi"
limits:
cpu: "100m"
memory: "50Mi"
securityContext:
privileged: false
capabilities:
add: ["NET_ADMIN"]
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
volumeMounts:
- name: run
mountPath: /run/flannel
- name: flannel-cfg
mountPath: /etc/kube-flannel/
volumes:
- name: run
hostPath:
path: /run/flannel
- name: cni
hostPath:
path: /etc/cni/net.d
- name: flannel-cfg
configMap:
name: kube-flannel-cfg
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: kube-flannel-ds-ppc64le
namespace: kube-system
labels:
tier: node
app: flannel
spec:
selector:
matchLabels:
app: flannel
template:
metadata:
labels:
tier: node
app: flannel
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: beta.kubernetes.io/os
operator: In
values:
- linux
- key: beta.kubernetes.io/arch
operator: In
values:
- ppc64le
hostNetwork: true
tolerations:
- operator: Exists
effect: NoSchedule
serviceAccountName: flannel
initContainers:
- name: install-cni
image: quay-mirror.qiniu.com/coreos/flannel:v0.11.0-ppc64le
command:
- cp
args:
- -f
- /etc/kube-flannel/cni-conf.json
- /etc/cni/net.d/10-flannel.conflist
volumeMounts:
- name: cni
mountPath: /etc/cni/net.d
- name: flannel-cfg
mountPath: /etc/kube-flannel/
containers:
- name: kube-flannel
image: quay-mirror.qiniu.com/coreos/flannel:v0.11.0-ppc64le
command:
- /opt/bin/flanneld
args:
- --ip-masq
- --kube-subnet-mgr
resources:
requests:
cpu: "100m"
memory: "50Mi"
limits:
cpu: "100m"
memory: "50Mi"
securityContext:
privileged: false
capabilities:
add: ["NET_ADMIN"]
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
volumeMounts:
- name: run
mountPath: /run/flannel
- name: flannel-cfg
mountPath: /etc/kube-flannel/
volumes:
- name: run
hostPath:
path: /run/flannel
- name: cni
hostPath:
path: /etc/cni/net.d
- name: flannel-cfg
configMap:
name: kube-flannel-cfg
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: kube-flannel-ds-s390x
namespace: kube-system
labels:
tier: node
app: flannel
spec:
selector:
matchLabels:
app: flannel
template:
metadata:
labels:
tier: node
app: flannel
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: beta.kubernetes.io/os
operator: In
values:
- linux
- key: beta.kubernetes.io/arch
operator: In
values:
- s390x
hostNetwork: true
tolerations:
- operator: Exists
effect: NoSchedule
serviceAccountName: flannel
initContainers:
- name: install-cni
image: quay-mirror.qiniu.com/coreos/flannel:v0.11.0-s390x
command:
- cp
args:
- -f
- /etc/kube-flannel/cni-conf.json
- /etc/cni/net.d/10-flannel.conflist
volumeMounts:
- name: cni
mountPath: /etc/cni/net.d
- name: flannel-cfg
mountPath: /etc/kube-flannel/
containers:
- name: kube-flannel
image: quay-mirror.qiniu.com/coreos/flannel:v0.11.0-s390x
command:
- /opt/bin/flanneld
args:
- --ip-masq
- --kube-subnet-mgr
resources:
requests:
cpu: "100m"
memory: "50Mi"
limits:
cpu: "100m"
memory: "50Mi"
securityContext:
privileged: false
capabilities:
add: ["NET_ADMIN"]
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
volumeMounts:
- name: run
mountPath: /run/flannel
- name: flannel-cfg
mountPath: /etc/kube-flannel/
volumes:
- name: run
hostPath:
path: /run/flannel
- name: cni
hostPath:
path: /etc/cni/net.d
- name: flannel-cfg
configMap:
name: kube-flannel-cfg
#所有主机尽量都pull一下也是可以的(先执行这个,三台机器都要有这个镜像)
docker pull quay.io/coreos/flannel:v0.12.0-amd64
#在master节点执行:
kubectl apply -f kube-flannel.yml
耐心等待30-60s 查看状态 是否为 ready状态
kubectl get nodes
如果还是都是为 notready状态
则需要修改 每台节点的:vi /var/lib/kubelet/kubeadm-flags.env # 删除–network-plugin=cni
#重新启动
则需要修改 每台节点的
systemctl daemon-reload
systemctl restart kubelet
整个k8s集群环境就搭建成功啦!
kubernetes部署nginx
在Master节点上执行
kubectl create deployment nginx --image=nginx:1.14-alpine
kubectl expose deployment nginx --port=80 --type=NodePort
kubectl get pods,service
每台服务器执行docker ps 查看nginx 运行具体在那一台
192.168.75.154:31347
k8s集群环境搞定!
kubectl get pods ---查看正在运行的pod
kubectl describe pod nginx-6867cdf567-kg88k ---查看正在运行的pod
kubernetes资源管理/清单配置基础
kubectl常用的命令
kubectl的命令可分为三类
1.陈述式命令(命令式对象管理) 类似于我们直接在docker 中 docker run 命令
2.陈述式对象配置(命令式对象配置) 类似于类似于 docker-compose.yml
3.声明式对象配置(声明式对象配置)
kubectl是k8s集群的命令行工具,通过它能够对集群本身进行管理,并能够在集群上进行容器化应用的安装部署,kubectl命令的语法如下:
kubectl [command] [type] [name] [flags]
comand:指定要对资源执行的操作,例如create、 get、delete
type:指定资源类型,比如deployment、pod、 service
name:指定资源的名称,名称大小写敏感
flags:指定额外的可选参数
kubectl get nodes
kubectl 常用命令
1.kubectl get nodes —查询k8s集群节点
2.kubectl get pod —查看所有的pod
3.kubectl describe pod nginx-6867cdf567-94kcb
查看pod详细内容
让后在我们的工作节点上执行 docker ps 查看该nginx 是否在运行
4.kubectl cluster-info —查看k8s 集群的信息
5.kubectl version 查看当前k8s 集群的版本
陈述式命令(命令式对象管理)
通过陈述式命令(命令式对象管理) 对namespace/pod操作
pod 是我们k8s 最小单元 容器运行在我们的pod里面
一个pod可以在里面运行n多个不同容器
1.命令形式创建一个namespace
kubectl create namespace mayikt-sit
2.查询所有的namespace
kubectl get ns
3.在mayikt-sit的namespace 下运行一个pod
4.查看mayikt-sit下的pod
kubectl get pods -n mayikt-sit
注意事项 查询pod 需要指定具体命名空间
kubectl get pods -n
默认查询 default namespace
5.查看该pod的详细信息
kubectl describe pod pod-864f9875b9-h467q (错误方式)
需要指定该pod对应的namespace 如果没有指定则会报错
kubectl describe pod pod-864f9875b9-h467q -n mayikt-sit (正确方式)
6.删除该pod
kubectl delete pods pod-864f9875b9-whqt6 -n mayikt-sit
但是删除该pod之后,有重新启动一个新的pod
kubectl get pods -n mayikt-sit
对比发现pod name 名称已经发生变化,让后查看该新的pod详细信息
kubectl describe pod pod-864f9875b9-jdp7k -n mayikt-sit
你会发现ip 也发生了变化。
我们应该通过删除命名空间,则自动会将这些pod删除
kubectl delete ns mayikt-sit
查看该命名空间下pod 已经没有该pod呢
命令式对象配置
命令式对象配置就是使用命令配合配置文件一起来操作k8s资源 类似于我们学习的
docker-compose 定义 yml 配置文件 需要对yaml 配置有一定了解。
kubectl create -f mayikt-pod1.yml 创建资源
kubectl delete -f mayikt-pod1.yml 删除资源
kubectl get-f mayikt-pod1.yml
1.创建 mayikt-pod1.yml
apiVersion: v1
kind: Namespace
metadata:
name: mayikt-sit #指定的Namespace空间名称
---
apiVersion: v1
kind: Pod
metadata:
name: mayikt-nginx-pod #指定pod的名称
namespace: mayikt-sit #指定该pod对应的Namespace
spec:
containers:
- name: mayikt-nginx-container #运行一个nginx容器
image: nginx:1.17.9 #指定镜像的名称
上传到服务器端
/usr/local 创建一个 mayikt 来演示我们的
mkdir mayikt
执行kubectl create -f mayikt-pod1.yml
创建成功 自动创建Namespace mayikt-sit 和 pod mayikt-nginx-pod
执行 kubectl get ns
执行 kubectl get pods -n mayikt-sit
查看该pod详细信息 kubectl describe pod mayikt-nginx-pod -n mayikt-sit
该容器运行在 164节点 执行curl 172.17.0.2 说明 pod中容器运行成功
执行get命令,查看资源 kubectl get -f mayikt-pod1.yml
删除delete 命令 kubectl delete -f mayikt-pod1.yml
namespace "mayikt-sit" deleted
pod "mayikt-nginx-pod" deleted
执行 kubectl get ns
在访问该nginx 已经访问不了
声明式对象配置
声明式对象配置跟命令式对象配置很类似,通过命令apply
kubectl apply -f mayikt-pod2.yml
在创建一个mayikt-pod2.yml
apiVersion: v1
kind: Namespace
metadata:
name: mayikt-sit #指定的Namespace空间名称
---
apiVersion: v1
kind: Pod
metadata:
name: mayikt-nginx-pod #指定pod的名称
namespace: mayikt-sit #指定该pod对应的Namespace
spec:
containers:
- name: mayikt-nginx-container #运行一个nginx容器
image: nginx:1.17.9 #指定镜像的名称
执行:kubectl apply -f mayikt-pod2.yml
查看 pod kubectl get pods -n mayikt-sit
查看pod 详细信息
kubectl describe pod mayikt-nginx-pod -n mayikt-sit
再次执行 kubectl apply -f mayikt-pod2.yml 资源没有发生任何变化
namespace/mayikt-sit unchanged
pod/mayikt-nginx-pod unchanged
未发生变化
修改nginx的版本1.17.8
再次执行:kubectl apply -f mayikt-pod2.yml
pod 是有发生变化的
查看pod 详细信息
kubectl describe pod mayikt-nginx-pod -n mayikt-sit
nginx:1.17.9 改成nginx:1.17.8
总结:
如果资源不存在就创建(create),相当于kubectl create
如果资源已存在,就更新(update),相当于kubectl patch
Namespace
1.Kubernetes 支持多个虚拟集群,它们底层依赖于同一个物理集群。 这些虚拟集群被称为命名空间。
可以实现多套环境的资源隔离或者多租户的资源隔离。
2.资源的名称需要在命名空间内是唯一的,但不能跨命名空间。命名空间不能相互嵌套,每个 Kubernetes 资源只能在一个命名空间中。命名空间是在多个用户之间划分集群资源的一种方法(通过资源配额)
3.k8s集群中的所有的Pod都是可以相互访问的,将两个Pod划分到不同的namespace下。kubernetes通过将集群内部的资源分配到不同的Namespace中,可以形成逻辑上的"组",以方便不同的组的资源进行隔离使用和管理,不同的Namespace下的pod 相互之间是访问不同的。
执行命令 kubectl get ns 查看所有的 Namespace
1.default 没有指明使用其它命名空间的对象所使用的默认命名空间
2.kube-system Kubernetes 系统创建对象所使用的命名空间
3.kube-public 这个命名空间是自动创建的,所有用户(包括未经过身份验证的用户)都可以读取它。这个命名空间主要用于集群使用,以防某些资源在整个集群中应该是可见和可读的。这个命名空间的公共方面只是一种约定,而不是要求。
创建Namespace
kubectl create ns mayikt-sit
删除Namespace
kubectl delete ns mayikt-sit
pod
Pod是在k8s集群进行管理的最小单元,程序要运行必须部署在容器(docker)中,而容器必须存在于Pod中。
Pod是对(docker)容器的封装,1个Pod中可以存在一个或者多个容器。
1.kubectl create ns mayikt-sit
2.运行一个 nginx pod
kubectl run nginx --image=nginx:1.17.9 --port=80 --namespace=mayikt-sit
3.kubectl get pod -n mayikt-sit 查看命名空间mayikt-sit下的pod
4.查看pod的ip
kubectl get pod -n mayikt-sit -o wide
5.更多pod详细信息
kubectl describe pod nginx-64777cd554-z6hgr -n mayikt-sit
6.删除pod
直接删除pod是删除不成功的 ,pod控制器有会重新启动一个pod
kubectl delete pod nginx-64777cd554-z6hgr -n mayikt-sit
继续执行 kubectl get pods -n mayikt-sit
我们将pod控制器删除 这样我们pod就可以删除啦
kubectl get deployment -n mayikt-sit 查询mayikt-sit下的控制器
删除pod控制器
kubectl delete deployment nginx -n mayikt-sit
kubectl get deployment -n mayikt-sit
kubectl get pods -n mayikt-sit
这样的我们的pod就被删除啦
Label
1.Label其实就一对 key/value ,被关联到对象上,比如Pod,标签的使用我们倾向于能够标示对象的特殊特点,Labels的值对系统本身并没有什么含义,只是对用户才有意义。同一个资源对象的labels属性的key必须唯一,label可以附加到各种资源对象上,如Node,Pod,Service,RC等。一个资源拥有多个标签,可以实现不同维度的管理。标签(Label)的组成: key=value。Label可以在创建对象时就附加到对象上,也可以在对象创建后通过API进行额外添加或修改
2.label 必须以字母或数字开头,可以使用字母、数字、连字符、点和下划线,最长63个字符。
3.当相同类型的资源越来越多,对资源划分管理是很有必要,此时就可以使用Label为资源对象 命名,以便于配置,部署等管理工作,提升资源的管理效率。label 作用类似Java包能对不同文件分开管理,让整体更加有条理,有利于维护。
4.通过Label来对对象进行引用。
例如:
1.版本标签:“version”:"“v1”, “version”:“v2”(灰度发布)
2.环境标签:“environment”:“sit”,“environment”:“pre”,“environment”:“prd”
创建一个mayikt-pod3.yml
apiVersion: v1
kind: Namespace
metadata:
name: mayikt-sit #指定的Namespace空间名称
---
apiVersion: v1
kind: Pod
metadata:
name: mayikt-nginx-pod #指定pod的名称
namespace: mayikt-sit #指定该pod对应的Namespace
spec:
containers:
- name: mayikt-nginx-container #运行一个nginx容器
image: nginx:1.17.9 #指定镜像的名称
执行命令:kubectl create -f mayikt-pod3.yml
查看标签 kubectl get pod -n mayikt-sit --show-labels
没有标签
为我们的pod打标签
kubectl label pod mayikt-nginx-pod -n mayikt-sit version=1.0
(注意需要更改自己的pod名称) mayikt-nginx-pod
执行命令:查看标签 kubectl get pod -n mayikt-sit --show-labels
更新标签
kubectl label pod mayikt-nginx-pod -n mayikt-sit version=2.0 --overwrite
查看标签 kubectl get pod -n mayikt-sit --show-labels
再启动一个新的pod
创建一个文件mayikt-pod4.yml
apiVersion: v1
kind: Namespace
metadata:
name: mayikt-sit #指定的Namespace空间名称
---
apiVersion: v1
kind: Pod
metadata:
name: mayikt-nginx-pod2 #指定pod的名称
namespace: mayikt-sit #指定该pod对应的Namespace
spec:
containers:
- name: mayikt-nginx-container #运行一个nginx容器
image: nginx:1.17.9 #指定镜像的名称
执行: kubectl create -f mayikt-pod4.yml
Error from server (AlreadyExists): error when creating “mayikt-pod4.yml”: namespaces “mayikt-sit” already exists
该错误可以忽略 因为该namespaces 已经存在。
执行kubectl get pod -n mayikt-sit -o wide
查看标签kubectl get pod -n mayikt-sit --show-labels
修改标签 kubectl label pod mayikt-nginx-pod2 -n mayikt-sit version=3.0 --overwrite
查看标签 kubectl get pod -n mayikt-sit --show-labels
配置文件的形式指定:
apiVersion: v1
kind: Namespace
metadata:
name: mayikt-pre #指定的Namespace空间名称
---
apiVersion: v1
kind: Pod
metadata:
name: mayikt-pre #指定pod的名称
namespace: mayikt-pre #指定该pod对应的Namespace
labels:
version: "8.0" #指定labels标签
env: "sit"
spec:
containers:
- name: mayikt-nginx-container #运行一个nginx容器
image: nginx:1.17.9 #指定镜像的名称
执行命令:kubectl create -f mayikt-pod5.yml
查看标签: kubectl get pod -n mayikt-pre --show-labels
搜索标签
kubectl get pods -l “version=2.0” -n mayikt-sit --show-labels
Deployment
Deployment为Pod和Replica Set提供声明式更新。
你只需要在 Deployment 中描述您想要的目标状态是什么,Deployment controller 就会帮您将 Pod 和ReplicaSet 的实际状态改变到您的目标状态。您可以定义一个全新的 Deployment 来创建 ReplicaSet 或者删除已有的 Deployment 并创建一个新的来替换。
注意:您不该手动管理由 Deployment 创建的 Replica Set,否则您就篡越了 Deployment controller 的职责!下文罗列了 Deployment 对象中已经覆盖了所有的用例。如果未有覆盖您所有需要的用例,请直接在 Kubernetes 的代码库中提 issue。
在k8s中,Pod是 最小的控制单元,我们的k8s不会直接控制Pod,而是通过Pod控制器来完成的。Pod控制器用于pod的管理,确保pod资源符合预期的状态,当pod的资源出现故障时,会尝试进行重启或重建pod。
清空之前的环境 删除之前的 命名空间
kubectl delete ns mayikt-sit
执行命令 创建命名空间 kubectl create ns mayikt-sit
创建nginx 集群 3个副本
--image 指定pod的镜像
--port 指定端口
--replicas 指定创建pod数量
--namespace 指定namespace
kubectl run nginx --image=nginx:1.17.9 --port=80 --replicas=3 --namespace=mayikt-sit
查看 pod的 ip 信息 kubectl get pod -n mayikt-sit -o wide
kubectl describe deployment nginx -n mayikt-sit
例如删除一个pod
kubectl delete pod nginx-5c9b49c46-df5tc -n mayikt-sit
kubectl get pod -n mayikt-sit -o wide
删除之后 通过控制器自动有创建的一个pod
kubectl describe pod nginx-5c9b49c46-zqv6g -n mayikt-sit
172.17.0.1 冲突原因是因为 在不同节点部署容器 只是容器ip冲突 但是它们分表部署在
164和165节点
kubectl describe pod nginx-5c9b49c46-n52dl -n mayikt-sit
Service
service是k8s中的一个重要概念,主要是提供负载均衡和服务自动发现
因为Pod IP会随着Pod的重建产生变化,可以使用Service提供的ip
来访问到我们的pod。
1.查看当前nginx的deployment
kubectl describe deployment nginx -n mayikt-sit
2.创建service
kubectl expose deploy nginx --name=mayikt-service01 --type=ClusterIP --target-port=80 -n mayikt-sit
3.查看命名空间下的service
kubectl get service -n mayikt-sit
4.查看命名空间下的service详细内容
kubectl get service -n mayikt-sit -o wide
我们可以通过 CLUSTER-IP(集群的IP),这就是service的IP,在Service的生命周期中,地址是不会变动的。
5.让后在工作节点上 执行
curl 10.99.114.200
6.以上方式无法外部,我们可以外部访问方式
只需要将–type 修改为NodePort
kubectl expose deploy nginx --name=mayikt-service02 --type=NodePort --target-port=80 -n mayikt-sit
7.在执行查看 该service
kubectl get pods,service -n mayikt-sit
8.打开浏览器使用工作节点的Ip
外部就可以访问啦!
9.删除service
service svc
kubectl delete svc mayikt-service01 -n mayikt-sit
kubectl delete svc mayikt-service02 -n mayikt-sit
10.kubectl get svc -n mayikt-sit 查看service
10.但是这种方式很麻烦我们可以直接定义成配置文件
创建一个 mayikt-serivce01.yml
apiVersion: v1
kind: Service
metadata :
name: mayikt-service01 ## Service名称
namespace: mayikt-sit ## 命名空间 mayikt -sit
spec:
clusterIP: 10.99.114.201
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
run: nginx
type: ClusterIP
11.执行 kubectl create -f mayikt-service-1.yml
12.执行 kubectl get pods,service -n mayikt-sit
13.工作节点上执行 curl 192.168.75.170
创建: kubectl create -f mayikt-service-1.yml
删除: kubectl delete -f mayikt-service-1.yml
筛选标签: kubectl get pods -l “version=2.0” -n mayikt-sit --show-labels
深入理解pod
pod相关概念
k8s中最小调度单元 ,一个pod里面可以有n多个不同的容器
1.Pod实际上是容器的集合,是k8s中最小调度单元
2.一个pod里面可以有n多个不同的容器
3.一个pod内的容器之间共享相同的podip网络
4.Pause容器,这是每个Pod都会有的一个根容器
5.可以在根容器上设置ip地址,其它容器都共享相同Ip (Pod IP),以实现Pod内部的网路通信
,Pod内部的通讯,Pod的之间的通讯采用虚拟二层网络技术来实现。
pod详细配置清单
apiVersion: v1 #必填,版本号,例如v1
kind: Pod #必填,资源类型,例如Pod、service、Deployment
metadata: #必填,元数据
name: mayikt-pod #必填,Pod名称
namespace: mayikt-namespace01 #Pod所属的命名空间, 默认为”default"
labels: #自定义标签列表
- name: v1
spec: #必填,Pod中容器的详细定义
containers: #必填 , Pod中容器列表
- name: mayikt-container01 #必填,容器名称
image: nginx:1.7.9 #必填, 容器的镜像名称
imagePullPolicy: [ Always Never |IfNotPresent] #获取镜像的策略
command: [string] #容器的启动命令 列表,如不指定,使用打包时使用的启动命令
args: [string] #容器的启动命令参数列表
workingDir: string #容器的工作目录
volumeMounts: #挂载到容器内部的存储卷配置
- name: string #引用pod定义的共享存储卷的名称,需用volumes[ ]部分定义的的卷名
mountPath: string #存储卷在容器内mount的绝对路径,应少于512字符
read0nly: boolean #是否为只读模式
ports: #需要暴露的端口库号列表
- name: string #端口的名称
containerPort: int #容器需要 监听的端口号
hostPort: int #容器所在主机需要监听的端口号,默认与Container相同
protocol: string #控端口协议,支持TCP和UDP,默认TCP
env: #容器运行前需设置的环境变量列表
- name: string #环境变量名称
value: string #环境变量的值
resources: #资源限制和请求的设置
limits: #资源限制的设置
cpu: string #Cpu的限制,单位为core数,将用于docker run --cpu-shares参数
memory: string #内存限制, 单位可以为Mib/Gib,将用于docker run --memory参数
requests: #资源请求的设置
cpu: string #Cpu请求,容器启动的初始可用数量
memory: string #内存请求,容器启动时的初始可用数量
lifecycle: #生命周期钩子
postStart: #容器启动后立即执行此钩子,如果执行失败,会根据重启策略进行重启
preStop: #容器终止前执行此钩子,无论结果如何,容器都会终止
livenessProbe: #树对Pod内各容器健康检查的设置, 当探测无响应几次后将自动重启该容器
exec: #对Pod容器内检查方式设置为exec方式
command: [string] #exec方式需要 制定的命令或脚本
httpGet: #对Pod内个容器健康检查方法设置为HttpGet,需要制定Path、port
path: string
port: number
host: string
scheme: string
HttpHeaders:
- name: string
value: string
tcpSocket: #对Pod内个容器 健康检查方式设置为tcpSocket方式
port: number
apiVersion: v1 # 必选,API的版本号
kind: Pod # 必选,类型Pod
metadata: # 必选,元数据即基础信息
name: nginx # 必选,符合RFC 1035规范的Pod名称
namespace: web-testing # 可选,不指定默认为default,Pod所在的命名空间
labels: # 可选,标签选择器,一般用于Selector
- app: nginx
annotations: # 可选,注释列表
- app: nginx
spec: # 必选,用于定义容器的详细信息
containers: # 必选,容器列表
name: nginx # 必选,符合RFC 1035规范的容器名称
image: nginx:v1 # 必选,容器所用的镜像的地址
imagePullPolicy: Always # 可选,镜像拉取策略
镜像拉取策略分三种:
Always不管镜像存不存在本地都拉取(默认)
Nerver 不管镜像存不存在本地都不拉取
IfNotpresent 本地有镜像不拉取,没有就拉取
workingDir: /usr/share/nginx/html # 可选,容器的工作目录
volumeMounts: # 可选,存储卷配置
name: webroot # 存储卷名称
mountPath: /usr/share/nginx/html # 挂载目录
readOnly: true # 只读
ports: # 可选,容器需要暴露的端口号列表
name: http # 端口名称
containerPort: 80 # 端口号
protocol: TCP # 端口协议,默认TCP
env: # 可选,环境变量配置
name: TZ # 变量名
value: Asia/Shanghai
name: LANG
value: en_US.utf8
resources: # 可选,资源限制和资源请求限制
limits: # 最大限制设置
cpu: 1000m
memory: 1024MiB
requests: # 启动所需的资源
cpu: 100m
memory: 512MiB
readinessProbe: # 可选,容器状态检查
httpGet: # 检测方式
path: / # 检查路径
port: 80 # 监控端口
timeoutSeconds: 2 # 超时时间
initialDelaySeconds: 60 # 初始化时间
livenessProbe: # 可选,监控状态检查
exec: # 检测方式
command:
- cat
- /health
httpGet: # 检测方式
path: /_health
port: 8080
httpHeaders:
- name: end-user
value: jason
tcpSocket: # 检测方式
port: 80
initialDelaySeconds: 60 # 初始化时间
timeoutSeconds: 2 # 超时时间
periodSeconds: 5 # 检测间隔
successThreshold: 2 # 检查成功为2次表示就绪
failureThreshold: 1 # 检测失败1次表示未就绪
securityContext: # 可选,限制容器不可信的行为
provoleged: false
restartPolicy: Always # 可选,默认为Always
nodeSelector: # 可选,指定Node节点
region: subnet7
imagePullSecrets: # 可选,拉取镜像使用的secret
name: default-dockercfg-86258
hostNetwork: false # 可选,是否为主机模式,如是,会占用主机端口
volumes: # 共享存储卷列表
name: webroot # 名称,与上述对应
emptyDir: {} # 共享卷类型,空
hostPath: # 共享卷类型,本机目录
path: /etc/hosts
secret: # 共享卷类型,secret模式,一般用于密码
secretName: default-token-tf2jp # 名称
defaultMode: 420 # 权限
configMap: # 一般用于配置文件
name: nginx-conf
defaultMode: 420
查看一级属性
kubectl explain pod — 查看一级属性
kubectl explain pod.metadata ----查看二级属性
kubectl explain pod.metadata.namespace----查看三级属性
在k8s中 一级属性 主要包含5个核心部分
1.apiVersion 版本,#必填,版本号,例如v1 由k8s内部定义, 版本号是通过kubectl api-versions 查询
2.kind 类型,必填,资源类型,例如Pod、service、Deployment等,通过kubectl api-resources查询
3.metadata <0bject> 元数据,主要是资源标识和说明,常用的有name、namespace、 labels等
4.spec 描述 对各种资源配置的详细描述
5.status 状态信息,需要我们定义 由k8s自动生成的
例如:
1.创建一个命名空间
kubectl create ns mayikt-sit
2.创建一个pod
kubectl run nginx --image=nginx:1.17.9 --port=80 --namespace=mayikt-sit
kubectl get pods -n mayikt-sit
kubectl get pods -n mayikt-sit nginx-5c9b49c46-7nqfq -o yaml 以yml格式展示
spec详细配置:
1.containers <[]0bject> 容器列表, 一个pod中可以有n多个不同的容器 用于定义容器的详细信息
2.nodeName 指定该pod运行到具体的node节点,根据nodeName的值将pod调度到指定的Node节点上
例如:node1 :192.168.110.1 node2 :192.168.110.2
3.nodeSelector <map[]> 根据标签的形式调度
4.hostNetwork 是否使用主机网络模式, 默认为false 如果设置为true,表示使用宿主机网络共享 容易产生端口冲突
5.volumes <[]0bject> 存储卷,用于定义Pod上面挂在的存储信息
6.restartPolicy Pod在遇到故障的时候重启策略
pod核心配置
pod基本配置1
apiVersion: v1
kind: Pod # 类型为pod
metadata:
name: mayikt-pod01
namespace: mayikt-sit
labels:
user: v1 ## 标签值
spec:
containers:
- name: nginx ##容器1
image: nginx:1.17.9
- name: mayikt-tomcat ##容器2
image: tomcat:8
1.kubectl delete ns mayikt-sit
2.kubectl create ns mayikt-sit
3.kubectl create -f mayikt-pod-info02.yml
4.kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit
查看容器详细信息
说明这两个pod都是启动状态
让后在192.168.75.175 节点 执行
curl 172.17.0.3 curl 172.17.0.3:8080
pod相关配置2
apiVersion: v1
kind: Pod # 类型为pod
metadata:
name: mayikt-pod01
namespace: mayikt-sit
labels:
user: v1 ## 标签值
spec:
containers:
- name: nginx1 ##容器1
image: nginx:1.17.9
- name: nginx2 ##容器2
image: nginx:1.17.9
1.kubectl delete ns mayikt-sit
2.kubectl create ns mayikt-sit
3.kubectl create -f mayikt-pod-info02.yml
4.kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit
pod内的容器共享相同的ip和端口空间 启动两个nginx 则端口冲突 第二个nginx 会不断重试
重试次数5次。
pod镜像拉取策略
apiVersion: v1
kind: Pod # 类型为pod
metadata:
name: mayikt-pod01
namespace: mayikt-sit
labels:
user: v1 ## 标签值
spec:
containers:
- name: nginx1 ##容器1
image: nginx:1.17.9
imagePullPolicy: IfNotPresent #用于设置镜像拉取策略
- name: nginx2 ##容器1
image: nginx:1.17.9
相关配置:
1.Always: 每次都是从远程仓库拉取镜像
2.IfNotPresent: 如果本地有该镜像则使用本地,如果本地没有该镜像则使用远程
3.Never: 只使用本地镜像,不去远程仓库拉取,本地没有该镜像则会报错
Never
只使用本地镜像,不去远程仓库拉取,本地没有该镜像则会报错
1
在node(工作节点)上执行 docker images
2.将工作节点上的nginx镜像删除
kubectl delete ns mayikt-sit 我们需要先删除 mayikt-sit命名空间 则会停止nginx容器
3.在工作节点上执行
docker rmi nginx:1.17.9
docker rmi nginx:latest
Never: 只使用本地镜像,不去远程仓库拉取,本地没有该镜像则会报错
apiVersion: v1
kind: Pod # 类型为pod
metadata:
name: mayikt-pod01
namespace: mayikt-sit
labels:
user: v1 ## 标签值
spec:
containers:
- name: nginx1 ##容器1
image: nginx:1.17.9
imagePullPolicy: Never #用于设置镜像拉取策略
kubectl create ns mayikt-sit
kubectl create -f mayikt-pod-info02.yml
4.kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit
IfNotPresent
如果本地有该镜像则使用本地,如果本地没有该镜像则使用远程
1.在node(工作节点)上执行 docker images
2.将工作节点上的nginx镜像删除
kubectl delete ns mayikt-sit 我们需要先删除 mayikt-sit命名空间 则会停止nginx容器
3.在工作节点上执行
docker rmi nginx:1.17.9
docker rmi nginx:latest
apiVersion: v1
kind: Pod # 类型为pod
metadata:
name: mayikt-pod01
namespace: mayikt-sit
labels:
user: v1 ## 标签值
spec:
containers:
- name: nginx1 ##容器1
image: nginx:1.17.9
imagePullPolicy: IfNotPresent #用于设置镜像拉取策略
kubectl create ns mayikt-sit
kubectl create -f mayikt-pod-info03.yml
4.kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit
第一次 从远处下载镜像
删除该命名空间 从新创建pod
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f mayikt-pod-info03.yml
kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit
第二次就没有从远处下载镜像
Always
每次都是从远程仓库拉取镜像
1.在node(工作节点)上执行 docker images
2.将工作节点上的nginx镜像删除
kubectl delete ns mayikt-sit 我们需要先删除 mayikt-sit命名空间 则会停止nginx容器
3.在工作节点上执行
docker rmi nginx:1.17.9
docker rmi nginx:latest
apiVersion: v1
kind: Pod # 类型为pod
metadata:
name: mayikt-pod01
namespace: mayikt-sit
labels:
user: v1 ## 标签值
spec:
containers:
- name: nginx1 ##容器1
image: nginx:1.17.9
imagePullPolicy: Always #用于设置镜像拉取策略
- name: nginx2 ##容器1
image: nginx:1.17.9
kubectl create ns mayikt-sit
kubectl create -f mayikt-pod-info03.yml
4.kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit
第一次运行pod
第二次运行pod
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f mayikt-pod-info03.yml
kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit
pod环境变量
apiVersion: v1
kind: Pod # 类型为pod
metadata:
name: mayikt-pod01
namespace: mayikt-sit
labels:
user: v1 ## 标签值
spec:
containers:
- name: nginx ##容器1
image: nginx:1.17.9
env: #设置环境变量列表
- name: "username"
value: "mayikt"
- name: "age"
value: "22"
1.kubectl delete ns mayikt-sit
2.kubectl create ns mayikt-sit
3.kubectl create -f mayikt-pod-info04.yml
4.kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit
5.进入 pod里面 容器
kubectl exec -it mayikt-pod01 -n mayikt-sit -c nginx /bin/sh
kubectl exec -it pod的名称 -n 命名空间 -c 容器名称 /bin/sh
输入echo $username
输入echo $age
端口相关设置
name <string> # 端口的名称,name在pod中是唯一的不允许重复
containerPort<integer> #容器要暴露的端口 (0<x<65536)
hostPort <integer> #容器要映射到主机上的端口
hostIP <string> # 容器要映射到主机的IP(-般省略)
protocol <string> # 端口协议,必须是UDP、TCP或SCTP。 默认为“TCP"。
apiVersion: v1
kind: Pod # 类型为pod
metadata:
name: mayikt-pod01
namespace: mayikt-sit
labels:
user: v1 ## 标签值
spec:
containers:
- name: nginx ##容器1
image: nginx:1.17.9
env: #设置环境变量列表
- name: "username"
value: "mayikt"
- name: "age"
value: "22"
ports: #设置容器暴露的端口列表
- name: mayikt-port
containerPort: 80
protocol: TCP
1.kubectl delete ns mayikt-sit
2.kubectl create ns mayikt-sit
3.kubectl create -f mayikt-pod-info05.yml
kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit
资源相关配置
可以通过资源配置 pod对应的 cpu核数、内存配置等
1.limits: 限制容器运行时的最大占用资源,当容器占用资源超过limits设置的值时会被终止,并进行重启;
2.requests :用于设置限制容器需要的最小资源,如果环境资源不够,容器则将无法启动
cpu: 核心数数
memory: 内存大小,可以使用Gi、Mi、G、M等形式
apiVersion: v1
kind: Pod # 类型为pod
metadata:
name: mayikt-pod01
namespace: mayikt-sit
labels:
user: v1 ## 标签值
spec:
containers:
- name: nginx ##容器1
image: nginx:1.17.9
resources: #资源配额
limits: #限制资源(上限) 最大资源限制
cpu: "2" #限制 CPU核心线程数
memory: "4Gi" #内存限制
requests: #请求资源(下限) 最小资源限制
cpu: "1" # CPU限制,单位是core数
memory: "5Mi" # 内存限制
1.kubectl delete ns mayikt-sit
2.kubectl create ns mayikt-sit
3.kubectl create -f mayikt-pod-info04.yml
kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit
演示内存不足
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
apiVersion: v1
kind: Pod # 类型为pod
metadata:
name: mayikt-pod01
namespace: mayikt-sit
labels:
user: v1 ## 标签值
spec:
containers:
- name: nginx ##容器1
image: nginx:1.17.9
resources: #资源配额
limits: #限制资源(上限) 最大资源限制
cpu: "2" #限制 CPU核心线程数
memory: "10Gi" #内存限制
requests: #请求资源(下限) 最小资源限制
cpu: "1" # CPU限制,单位是core数
memory: "10Gi" # 内存限制
启动命令配置
容器启动成功之后 可以执行一些脚本
创建一个mayikt-pod01
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
apiVersion: v1
kind: Pod
metadata:
name: mayikt-pod01
namespace: mayikt-sit
spec:
containers:
- name: nginx
image: nginx:1.17.9
- name: busybox
image: busybox:1.30
执行kubectl create -f pod-initcontainer-demo01.yml
kubectl get pods -n mayikt-sit 查看pod信息 busybox停止了
kubectl describe pods -n mayikt-sit
这是因为busybox容器启动后,它会自动关闭,我们通过启动命令写脚本,让busybox一直在运行。
apiVersion: v1
kind: Pod
metadata:
name: mayikt-pod01
namespace: mayikt-sit
spec:
containers:
- name: nginx
image: nginx:1.17.9
- name: busybox
image: busybox:1.30
command: [ "/bin/sh","-c","while true;do sleep 3; done;"]
“/bin/sh”,“-C”,使用sh执行命令 一直死循环 while true;do sleep 3; done;
为了避免cpu飙高的问题 休眠3s时间。
kubernetes集群环境重置
1.需要在每台节点执行 kubeadm reset
2.在主节点 执行 rm -rf $HOME/.kube
3.直接回到k8s 初始化流程
kubectl如何在工作节点执行
kubecti的运行在工作节点是需要额外进行配置的,它的配置文件是$HOME/.kube,如果想要在node节点运行此命令,需要将master上的.kube文件复制到node节点上,即在master节点上执行下面操作:
scp -r ~/.kube node2:~/
允许在node1节点上执行kubectl get nodes
kubernetes常见错误
1.在Master节点执行: kubectl get nodes
报错:
The connection to the server localhost:8080 was refused - did you specify the right host or port?
原因:kubenetes master没有与本机绑定,集群初始化的时候没有设置
在Master节点执行 export KUBECONFIG=/etc/kubernetes/admin.conf
2.初始化K8S master时报错
The HTTP call equal to ‘curl -sSL http://localhost:10248/healthz‘ failed with error: Get “http://loc
journalctl -xeu kubelet
3.执行kubeadm init 报错:
[ERROR FileAvailable–etc-kubernetes-manifests-kube-scheduler.yaml]: /etc/kubernetes/manifests/kube-scheduler.yaml already exists
kubeadm reset 重置 即可 在执行 kubeadm init
注意:kubeadm reset 重置 需要在 主节点执行 rm -rf $HOME/.kube
4
执行 kubeadm init 报错kubelet-check] The HTTP call equal to ‘curl -sSL http://localhost:10248/healthz‘ fa
journalctl -xeu kubelet -l 查看具体错误日志 在根据具体报错日志分析
5.执行 kubeadm init Unable to connect to the server: x509: certificate signed by unknown authority (possibly because of “crypto/rsa: verification error” while trying to verify candidate authority certificate “kubernetes”)
你在执行 kubeadm reset命令后没有删除创建的 $HOME/.kube目录
rm -rf $HOME/.kube
6.Unable to connect to the server: dial tcp 192.168.75.163:6443: connect: no route to host
kubectl cluster-info —查询集群信息
Unable to connect to the server: dial tcp 192.168.75.163:6443: connect: no route to host
主节点的ip地址发生了变化 变成了 192.168.75.166:6443
kubeadm reset 重置 即可 在执行 kubeadm init
7.kubectl get node 显示 NotReady 解决方法
解决方法:
查看日志 tail -f /var/log/message
发现是防火墙问题。处理方法:
关闭各个节点的防火墙:
systemctl status firewalld
systemctl stop firewalld
systemctl enable firewalld
重启node节点:
[root@k8s_node02 bin]# systemctl daemon-reload
[root@k8s_node02 bin]# systemctl restart docker
[root@k8s_node02 bin]# systemctl restart kubelet
8.The Pod “mayikt-pod” is invalid: spec.containers[0].ports[0].name: Invalid value: “mayikt-nginx-port”: must be no more than 15 characters
原因是
ports:
- name: mayikt-nginx-port
containerPort: 80
原因是名称太长
ports:
- name: nginx-port
containerPort: 80
9.执行kubectl get nodes 显示 节点ip 不是host文件指定的名称 则直接重启虚拟机
重置节点即可。