简介:摘自 尚硅谷雷锋阳老师的语雀文档
学会使用按量付费的云服务器,开发测试性价比高
和网络有关的概念,如何在云服务器开通一个集群
一个云服务器有两个IP:公网IP和私网IP
公网IP:对外暴露资源的访问,可能会发生改变,按量付费服务器每次启动可能都会发生改变
私网IP:服务器内部网卡使用的IP,需要固定不变,集群内部交互用
VPC:私有网络、专有网络
将IP地址转化为二进制就是如下,每个段有八位二进制,16掩码表示掩去前16位,只后16位变化,而8位最大二进制 11111111
转化为10 进制就是 256 ,而IP包括一个零那就是255,所以此网段的变化为
192.168.0.0 ~ 192.168.255.255
有 65536 个IP
通过子网计算,实际可用为65534个
因为专有网络的可用IP太多了不好区分,单16位掩码的IP就有65534个,所以交换机的作用是用来规定专有网络下的哪些IP能用,避免专有网络使用太过混乱
在创建专有网络时同时制定或创建交换机,如下图的设定,表示创建24位掩码,指定第三段的号段,那么可用IP就在第4号段变化,将可用IP由65534个缩小到了252个,避免了混乱
不同VPC网络下,即使私有网络IP相同,他们之间内部是无法平通的,所以一个VPC相当于一个局域网的隔离,
差异化保存
资源隔离
● cpu、memory资源隔离与限制
● 访问设备隔离与限制
● 网络隔离与限制
● 用户、用户组隔离限制
1、移除以前docker相关包
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
2、配置yum源
sudo yum install -y yum-utils
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
3、安装docker
sudo yum install -y docker-ce docker-ce-cli containerd.io
#以下是在安装k8s的时候使用 指定版本
yum install -y docker-ce-20.10.7 docker-ce-cli-20.10.7 containerd.io-1.4.6
4、启动和开机启动
systemctl enable docker --now
5、配置加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://vgcihl1j.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
1、找镜像
docker pull nginx #下载最新版
镜像名:版本名(标签)
docker pull nginx:1.20.1
docker pull redis #下载最新
docker pull redis:6.2.4
## 下载来的镜像都在本地
docker images #查看所有镜像
redis = redis:latest
docker rmi 镜像名:版本号/镜像id
2、启动容器
启动nginx应用容器,并映射88端口,测试的访问
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
【docker run 设置项 镜像名 】 镜像启动运行的命令(镜像里面默认有的,一般不会写)
# -d:后台运行
# --restart=always: 开机自启
docker run --name=mynginx -d --restart=always -p 88:80 nginx
# 端口映射 [-p 主机端口:容器端口]
# 查看正在运行的容器
docker ps
# 查看所有
docker ps -a
# 删除停止的容器
docker rm 容器id/名字
docker rm -f mynginx #强制删除正在运行中的
#停止容器
docker stop 容器id/名字
#再次启动
docker start 容器id/名字
#应用开机自启
docker update 容器id/名字 --restart=always
3、进入容器修改内容
[root@i-r686cdnl ~] docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
33040453a360 nginx "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 0.0.0.0:88->80/tcp, :::88->80/tcp mynginx
[root@i-r686cdnl ~] docker exec -it 33040453a360 /bin/sh
root@33040453a360:/bin] cd /usr/share/nginx/html
root@33040453a360:/usr/share/nginx/html] echo "hello atguigu
" > index.html
docker run --name=mynginx \
-d --restart=always \
-p 88:80 \
-v /data/html:/usr/share/nginx/html:ro \
nginx
# -v 主机目录:容器目录:读写权限
# 修改页面只需要去 主机的 /data/html
4、提交改变
将指定容器提交成新容器
[root@i-r686cdnl ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
33040453a360 nginx "/docker-entrypoint.…" 12 minutes ago Up 12 minutes 0.0.0.0:88->80/tcp, :::88->80/tcp mynginx
[root@i-r686cdnl ~]# docker commit --help
Usage: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
Create a new image from a container's changes
Options:
-a, --author string Author (e.g., "John Hannibal Smith " )
-c, --change list Apply Dockerfile instruction to the created image
-m, --message string Commit message
-p, --pause Pause container during commit (default true)
[root@i-r686cdnl ~] docker commit -a "作者" -m "描述" 33040453a360 gugunginx:v1.0
sha256:50eecfacab35a36f8dfd3aefd205e04dfe5742e590fdc6061aaf490ecedfa3bf
[root@i-r686cdnl ~] docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
gugunginx v1.0 50eecfacab35 6 seconds ago 133MB
nginx latest 87a94228f133 9 days ago 133MB
镜像传输
# 将镜像保存成压缩包
docker save -o abc.tar guignginx:v1.0
# 别的机器加载这个镜像
docker load -i abc.tar
# 离线安装
5、推送远程仓库
推送镜像到docker hub;应用市场
docker tag local-image:tagname new-repo:tagname
docker push new-repo:tagname
# 把旧镜像的名字,改成仓库要求的新版名字
docker tag guignginx:v1.0 leifengyang/guignginx:v1.0
# 登录到docker hub
docker login
docker logout(推送完成镜像后退出)
# 推送
docker push leifengyang/guignginx:v1.0
# 别的机器下载
docker pull leifengyang/guignginx:v1.0
6、补充
docker logs 容器名/id 排错
docker exec -it 容器id /bin/bash
# docker 经常修改nginx配置文件
docker run -d -p 80:80 \
-v /data/html:/usr/share/nginx/html:ro \
-v /data/conf/nginx.conf:/etc/nginx/nginx.conf \
--name mynginx-02 \
nginx
#把容器指定位置的东西复制出来
docker cp 5eff66eec7e1:/etc/nginx/nginx.conf /data/conf/nginx.conf
#把外面的内容复制到容器里面
docker cp /data/conf/nginx.conf 5eff66eec7e1:/etc/nginx/nginx.conf
部署一个Redis+应用,尝试应用操作Redis产生数据
注意先创建好主机的文件挂载目录和配置文件
mkdir -p /data/redis/
vi redis.conf
appendonly yes
-------------------------------
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
#redis使用自定义配置文件启动
docker run \
-v /data/redis/redis.conf:/etc/redis/redis.conf \
-v /data/redis/data:/data \
-d --name myredis \
-p 6379:6379 \
redis:latest redis-server /etc/redis/redis.conf #启动时额外命令 redis-server 以/etc/redis/redis.conf 配置文件加载启动
设置redis密码登录
vi redis.conf
requirepass 123xxx
docker restart myredis #重启redis
1、用redis简单的统计功能
@RestController
public class CounterController {
@Autowired
StringRedisTemplate redisTemplate;
@GetMapping("/hello")
public String count(){
Long increment = redisTemplate.opsForValue().increment("count-people");
return "有"+ increment +" 访问了页面";
}
}
2、将应用打包成镜像
以前:Java为例
现在:所有机器都安装Docker,任何应用都是镜像,所有机器都可以运行
3、怎么打包-Dockerfile
FROM openjdk:8-jdk-slim #基础运行环境,相当去掉了 duoker pull
LABEL maintainer=leifengyang #作者
COPY target/*.jar /app.jar # 将当前项目 目录 复制到 容器 的
ENTRYPOINT ["java","-jar","/app.jar"] # 镜像的启动命令
运行Dockerfile打包成镜像,默认不用输Dockerfile,注意末尾有一个 点,表示在当前目录下工作
docker build -t java-demo:v1.0 .
3、启动容器
docker run -d -p 8080:8080 --name myjava-app java-demo:v1.0
docker logs 容器id
查看日志,容器和项目启动成功,在网络正常访问
分享镜像
# 登录docker hub
docker login
#给旧镜像起名
docker tag java-demo:v1.0 leifengyang/java-demo:v1.0
# 推送到docker hub
docker push leifengyang/java-demo:v1.0
# 别的机器
docker pull leifengyang/java-demo:v1.0
# 别的机器运行
docker run -d -p 8080:8080 --name myjava-app java-demo:v1.0
kubernetes具有以下特性:
Kubernetes 为你提供了一个可弹性运行分布式系统的框架。 Kubernetes 会满足你的扩展要求、故障转移、部署模式等。 例如,Kubernetes 可以轻松管理系统的 Canary 部署。
架构
1、工作方式
Kubernetes Cluster = N Master Node + N Worker Node:N主节点+N工作节点; N>=1
1、控制平面组件(Control Plane Components)
控制平面的组件对集群做出全局决策(比如调度),以及检测和响应集群事件(例如,当不满足部署的 replicas 字段时,启动新的 pod)。
控制平面组件可以在集群中的任何节点上运行。 然而,为了简单起见,设置脚本通常会在同一个计算机上启动所有控制平面组件, 并且不会在此计算机上运行用户容器。 请参阅使用 kubeadm 构建高可用性集群 中关于多 VM 控制平面设置的示例。
kube-apiserver
API 服务器是 Kubernetes 控制面的组件, 该组件公开了 Kubernetes API。 API 服务器是 Kubernetes 控制面的前端。
Kubernetes API 服务器的主要实现是 kube-apiserver。 kube-apiserver 设计上考虑了水平伸缩,也就是说,它可通过部署多个实例进行伸缩。 你可以运行 kube-apiserver 的多个实例,并在这些实例之间平衡流量。
etcd
etcd 是兼具一致性和高可用性的键值数据库,可以作为保存 Kubernetes 所有集群数据的后台数据库。
您的 Kubernetes 集群的 etcd 数据库通常需要有个备份计划。
要了解 etcd 更深层次的信息,请参考 etcd 文档。
kube-scheduler
控制平面组件,负责监视新创建的、未指定运行节点(node)的 Pods,选择节点让 Pod 在上面运行。
调度决策考虑的因素包括单个 Pod 和 Pod 集合的资源需求、硬件/软件/策略约束、亲和性和反亲和性规范、数据位置、工作负载间的干扰和最后时限。
kube-controller-manager
在主节点上运行 控制器 的组件。
从逻辑上讲,每个控制器都是一个单独的进程, 但是为了降低复杂性,它们都被编译到同一个可执行文件,并在一个进程中运行。
这些控制器包括:
● 节点控制器(Node Controller): 负责在节点出现故障时进行通知和响应
● 任务控制器(Job controller): 监测代表一次性任务的 Job 对象,然后创建 Pods 来运行这些任务直至完成
● 端点控制器(Endpoints Controller): 填充端点(Endpoints)对象(即加入 Service 与 Pod)
● 服务帐户和令牌控制器(Service Account & Token Controllers): 为新的命名空间创建默认帐户和 API 访问令牌
cloud-controller-manager
云控制器管理器是指嵌入特定云的控制逻辑的 控制平面组件。 云控制器管理器允许您链接集群到云提供商的应用编程接口中, 并把和该云平台交互的组件与只和您的集群交互的组件分离开。
cloud-controller-manager 仅运行特定于云平台的控制回路。 如果你在自己的环境中运行 Kubernetes,或者在本地计算机中运行学习环境, 所部署的环境中不需要云控制器管理器。
与 kube-controller-manager 类似,cloud-controller-manager 将若干逻辑上独立的 控制回路组合到同一个可执行文件中,供你以同一进程的方式运行。 你可以对其执行水平扩容(运行不止一个副本)以提升性能或者增强容错能力。
下面的控制器都包含对云平台驱动的依赖:
● 节点控制器(Node Controller): 用于在节点终止响应后检查云提供商以确定节点是否已被删除
● 路由控制器(Route Controller): 用于在底层云基础架构中设置路由
● 服务控制器(Service Controller): 用于创建、更新和删除云提供商负载均衡器
2、Node 组件
节点组件在每个节点上运行,维护运行的 Pod 并提供 Kubernetes 运行环境。
kubelet
一个在集群中每个节点(node)上运行的代理。 它保证容器(containers)都 运行在 Pod 中。
kubelet 接收一组通过各类机制提供给它的 PodSpecs,确保这些 PodSpecs 中描述的容器处于运行状态且健康。 kubelet 不会管理不是由 Kubernetes 创建的容器。
kube-proxy
kube-proxy 是集群中每个节点上运行的网络代理, 实现 Kubernetes 服务(Service) 概念的一部分。
kube-proxy 维护节点上的网络规则。这些网络规则允许从集群内部或外部的网络会话与 Pod 进行网络通信。
如果操作系统提供了数据包过滤层并可用的话,kube-proxy 会通过它来实现网络规则。否则, kube-proxy 仅转发流量本身。
准备搭建的架构图
创建vpc及其私有网络
创建三台按需付费服务器 2c4t ,指定刚创建好的vpc网络,分配三个公网IP,安全组内打开组内互信这样内部IP互通就可以绕开防火墙
ssh工具连接,指定一个做为master
一个master 两个node
参考上面docker安装
#各个机器设置自己的域名
hostnamectl set-hostname xxxx
# 将 SELinux 设置为 permissive 模式(相当于将其禁用)禁用安全模式
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
#关闭swap # free -m 查看swap
swapoff -a
sed -ri 's/.*swap.*/#&/' /etc/fstab
#允许 iptables 检查桥接流量
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF
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
安装kubelet、kubeadm、kubectl
# 设置镜像源
cat <<EOF | sudo tee /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
exclude=kubelet kubeadm kubectl
EOF
# 拉取三大件
sudo yum install -y kubelet-1.20.9 kubeadm-1.20.9 kubectl-1.20.9 --disableexcludes=kubernetes
# 启动和自启这个大件
sudo systemctl enable --now kubelet
1、提前下载各个机器需要的镜像,避免因网络原因造成的安装失败
# 生成一个sh文件,循环下载定义的镜像
sudo tee ./images.sh <<-'EOF'
#!/bin/bash
images=(
kube-apiserver:v1.20.9
kube-proxy:v1.20.9
kube-controller-manager:v1.20.9
kube-scheduler:v1.20.9
coredns:1.7.0
etcd:3.4.13-0
pause:3.2
)
for imageName in ${images[@]} ; do
docker pull registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/$imageName
done
EOF
# 给文件执行权限并执行
chmod +x ./images.sh && ./images.sh
2、初始化主节点
#所有机器添加master域名映射,以下需要修改为自己的master节点的私网IP
# 让所有节点知道主节点的位置IP
echo "172.31.0.2 cluster-endpoint" >> /etc/hosts
#主节点初始化
kubeadm init \
--apiserver-advertise-address=172.31.0.2 \
--control-plane-endpoint=cluster-endpoint \
--image-repository registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images \
--kubernetes-version v1.20.9 \
--service-cidr=10.96.0.0/16 \
--pod-network-cidr=192.168.0.0/16
#所有网络范围不重叠
初始化后返回的信息
Your Kubernetes control-plane has initialized successfully!
# 第一步 要使用这个集群还要执行下面这些步骤。需要马上执行
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
# 还应该再来部署一个pod网络插件,这个插件将集群之间的机器打通互相通讯
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
# 你可以加入任意多的主节点
You can now join any number of control-plane nodes by copying certificate authorities
and service account keys on each node and then running the following as root:
kubeadm join cluster-endpoint:6443 --token 2n4gns.e3n0mqlip1nmbbqa \
--discovery-token-ca-cert-hash sha256:786bc6e4ac9d96e6d6764d94b16e4cd40e599669e4824ebba5a7eba31bb2a983 \
--control-plane
# 还可以加入任意多的工作节点,运行下面的kubeadm加入子节点
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join cluster-endpoint:6443 --token epjqlx.25mfge9y4rgw1n4o \
--discovery-token-ca-cert-hash sha256:5298e8db61faebe5eca8bfc5ec788d5f9bb4bad16dbe924027d33c05416c3738
运行上面第一步,完成主节点创建
现在能用到的一些命令
#查看集群所有节点
kubectl get nodes
#根据配置文件,给集群创建资源
kubectl apply -f xxxx.yaml
#查看集群部署了哪些应用?
docker ps === kubectl get pods -A
# 运行中的应用在docker里面叫容器,在k8s里面叫Pod
kubectl get pods -A
3、安装网络组件
curl https://docs.projectcalico.org/manifests/calico.yaml -O
kubectl apply -f calico.yaml
4、加入node节点
在子节点,运行上面初始化master节点时生成的命令,这个命令24小时内有效
kubeadm join cluster-endpoint:6443 --token 2n4gns.e3n0mqlip1nmbbqa \
--discovery-token-ca-cert-hash sha256:786bc6e4ac9d96e6d6764d94b16e4cd40e599669e4824ebba5a7eba31bb2a983
若令牌过期,主节点创建新令牌
kubeadm token create --print-join-command
等待一会查看节点准备状况,至此k8s集群准备就绪
[root@k8s-master ~] kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane,master 34m v1.20.9
k8s-node1 Ready <none> 83s v1.20.9
k8s-node2 Ready <none> 78s v1.20.9
1、部署
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.3.1/aio/deploy/recommended.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: v1
kind: Namespace
metadata:
name: kubernetes-dashboard
---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
---
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
ports:
- port: 443
targetPort: 8443
selector:
k8s-app: kubernetes-dashboard
---
apiVersion: v1
kind: Secret
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-certs
namespace: kubernetes-dashboard
type: Opaque
---
apiVersion: v1
kind: Secret
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-csrf
namespace: kubernetes-dashboard
type: Opaque
data:
csrf: ""
---
apiVersion: v1
kind: Secret
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-key-holder
namespace: kubernetes-dashboard
type: Opaque
---
kind: ConfigMap
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-settings
namespace: kubernetes-dashboard
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
rules:
# Allow Dashboard to get, update and delete Dashboard exclusive secrets.
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs", "kubernetes-dashboard-csrf"]
verbs: ["get", "update", "delete"]
# Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map.
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["kubernetes-dashboard-settings"]
verbs: ["get", "update"]
# Allow Dashboard to get metrics.
- apiGroups: [""]
resources: ["services"]
resourceNames: ["heapster", "dashboard-metrics-scraper"]
verbs: ["proxy"]
- apiGroups: [""]
resources: ["services/proxy"]
resourceNames: ["heapster", "http:heapster:", "https:heapster:", "dashboard-metrics-scraper", "http:dashboard-metrics-scraper"]
verbs: ["get"]
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
rules:
# Allow Metrics Scraper to get metrics from the Metrics server
- apiGroups: ["metrics.k8s.io"]
resources: ["pods", "nodes"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: kubernetes-dashboard
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kubernetes-dashboard
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: kubernetes-dashboard
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kubernetes-dashboard
---
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
k8s-app: kubernetes-dashboard
template:
metadata:
labels:
k8s-app: kubernetes-dashboard
spec:
containers:
- name: kubernetes-dashboard
image: kubernetesui/dashboard:v2.3.1
imagePullPolicy: Always
ports:
- containerPort: 8443
protocol: TCP
args:
- --auto-generate-certificates
- --namespace=kubernetes-dashboard
# Uncomment the following line to manually specify Kubernetes API server Host
# If not specified, Dashboard will attempt to auto discover the API server and connect
# to it. Uncomment only if the default does not work.
# - --apiserver-host=http://my-address:port
volumeMounts:
- name: kubernetes-dashboard-certs
mountPath: /certs
# Create on-disk volume to store exec logs
- mountPath: /tmp
name: tmp-volume
livenessProbe:
httpGet:
scheme: HTTPS
path: /
port: 8443
initialDelaySeconds: 30
timeoutSeconds: 30
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsUser: 1001
runAsGroup: 2001
volumes:
- name: kubernetes-dashboard-certs
secret:
secretName: kubernetes-dashboard-certs
- name: tmp-volume
emptyDir: {
}
serviceAccountName: kubernetes-dashboard
nodeSelector:
"kubernetes.io/os": linux
# Comment the following tolerations if Dashboard must not be deployed on master
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
---
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: dashboard-metrics-scraper
name: dashboard-metrics-scraper
namespace: kubernetes-dashboard
spec:
ports:
- port: 8000
targetPort: 8000
selector:
k8s-app: dashboard-metrics-scraper
---
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
k8s-app: dashboard-metrics-scraper
name: dashboard-metrics-scraper
namespace: kubernetes-dashboard
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
k8s-app: dashboard-metrics-scraper
template:
metadata:
labels:
k8s-app: dashboard-metrics-scraper
annotations:
seccomp.security.alpha.kubernetes.io/pod: 'runtime/default'
spec:
containers:
- name: dashboard-metrics-scraper
image: kubernetesui/metrics-scraper:v1.0.6
ports:
- containerPort: 8000
protocol: TCP
livenessProbe:
httpGet:
scheme: HTTP
path: /
port: 8000
initialDelaySeconds: 30
timeoutSeconds: 30
volumeMounts:
- mountPath: /tmp
name: tmp-volume
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsUser: 1001
runAsGroup: 2001
serviceAccountName: kubernetes-dashboard
nodeSelector:
"kubernetes.io/os": linux
# Comment the following tolerations if Dashboard must not be deployed on master
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
volumes:
- name: tmp-volume
emptyDir: {
}
2、设置访问端口
这里需要修改集群中的资源
kubectl edit svc kubernetes-dashboard -n kubernetes-dashboard
kubectl get svc -A |grep kubernetes-dashboard
## 找到端口,在安全组放行
访问: https://集群任意IP:端口
3、创建访问账号
#创建访问账号,准备一个yaml文件; vi dash.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard
kubectl apply -f dash.yaml
4、令牌访问
#获取访问令牌
kubectl -n kubernetes-dashboard get secret $(kubectl -n kubernetes-dashboard get sa/admin-user -o jsonpath="{.secrets[0].name}") -o go-template="{
{.data.token | base64decode}}"
复制返回的密钥就能登录
名称空间用来对资源隔离划分。默认只隔离资源,不隔离网络
创建删除名称空间
kubectl create ns hello
kubectl delete ns hello
通过文件创建名称空间
apiVersion: v1
kind: Namespace
metadata:
name: hello
通过文件创建的ns也通过文件删除
kubectl apply -f hello.yml
kubectl delete -f hello.yml
运行中的一组
容器,Pod是kubernetes中应用的最小单位。一个pod中可能包含多个docker的容器
查看pod能看到ready, 准备好的容器数量/总共的容器数量
kubectl命令行方式创建第一个pod
# 运行一个容器名字为mynginx 以 镜像nginx
kubectl run mynginx --image=nginx
# 查看default名称空间的Pod
kubectl get pod
# 描述
kubectl describe pod 你自己的Pod名字
# 删除
kubectl delete pod Pod名字
# 查看Pod的运行日志
kubectl logs Pod名字
# 每个Pod - k8s都会分配一个ip
kubectl get pod -owide
# 使用Pod的ip+pod里面运行容器的端口
curl 192.168.169.136
# 集群中的任意一个机器以及任意的应用都能通过Pod分配的ip来访问这个Pod
以配置文件创建
apiVersion: v1
kind: Pod
metadata:
labels:
run: mynginx
name: mynginx
# namespace: default
spec:
containers:
- image: nginx
name: mynginx
kubectl apply -f 配置文件
kubectl delete -f 配置文件
可视化控制台直接查看容器日志,和进入容器的内部相当于 docker exec -it /bin/bash
# 进入容器,交互模式
kubectl exec -it myapp -- /bin/bash
# 每个Pod - k8s都会分配一个ip
kubectl get pod -owide
# 使用Pod的ip+pod里面运行容器的端口;集群内访问
curl 192.168.169.136
一个pod中启动两个容器
apiVersion: v1
kind: Pod
metadata:
labels:
run: myapp
name: myapp
spec:
containers:
- image: nginx
name: nginx
- image: tomcat:8.5.68
name: tomcat
控制Pod,使Pod拥有多副本,自愈,扩缩容等能,
即使主动执行删除pod指令kubectl delete pod xxx
,集群也会恢复这个pod,这就是自愈
# 清除所有Pod,比较下面两个命令有何不同效果?
kubectl run mynginx --image=nginx
kubectl create deployment mytomcat --image=tomcat:8.5.68
# 自愈能力
多副本部署
kubectl create deployment my-dep --image=nginx --replicas=3
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: my-dep
name: my-dep
spec:
replicas: 3
selector:
matchLabels:
app: my-dep
template:
metadata:
labels:
app: my-dep
spec:
containers:
- image: nginx
name: nginx
查看部署
kubectl get deploy xxxx
kubectl scale --replicas=5 deployment/my-dep
启动了一个deployment有三个容器部署,其中node2两个,node1一个
我们关机node2服务器,集群默认5分钟后才会做故障转移工作
# 查看pod详细信息
kubectl get pod -owide
# 监控pod
kubectl get pod -w
4、滚动更新
不停机更新,更改deploy对部署镜像,集群就会对deploy进行更新,老的镜像容器不回立马停机,而是等到新镜像容器启动成功后再替换掉老镜像容器,完成了不停机更新、滚动部署
# 获取deploy部署的 yaml信息,详细查看具体用的什么镜像
kubectl get deploy my-dep -oyaml
# 修改dep的镜像,修改完成后立即开始滚动部署
kubectl set image deployment/my-dep nginx=nginx:1.16.1 --record
kubectl rollout status deployment/my-dep
5、版本回退
#历史记录
kubectl rollout history deployment/my-dep
#查看某个历史详情
kubectl rollout history deployment/my-dep --revision=2
#回滚(回到上次)
kubectl rollout undo deployment/my-dep
#回滚(回到指定版本)
kubectl rollout undo deployment/my-dep --to-revision=2
# 获取部署的信息以yml输出 筛选image
kubectl get deploy/my-dep -oyaml|grep image
除了Deployment,k8s还有 StatefulSet 、DaemonSet 、Job 等 类型资源。我们都称为 工作负载。
有状态应用使用 StatefulSet 部署,无状态应用使用 Deployment 部署
https://kubernetes.io/zh/docs/concepts/workloads/controllers/
其他工作负载
Service
将一组 Pods 公开为网络服务的抽象方法。
#暴露Deploy 指定外部端口8000映射至集群内部端口80
kubectl expose deployment my-dep --port=8000 --target-port=80 --type=ClusterIP
# 查询service暴露的ip
kubectl get svc
#使用标签检索Pod
kubectl get pod -l app=my-dep
服务器内部就可以用暴露的IP访问
集群内部额外的还能使用service名.命名空间.svc:端口
curl my-dep.default.svc:8000
但是此时,集群外,服务器无法直接用service名访问
service的服务发现,下线pod 流量会自动转到其他service的pod不影响访问,再加入pod也会自动负载均衡
1、ClusterIP
# 等同于没有可以不加 --type 默认clusterIP,集群内访问
kubectl expose deployment my-dep --port=8000 --target-port=80 --type=ClusterIP
2、NodePort
kubectl expose deployment my-dep --port=8000 --target-port=80 --type=NodePort
先删除之前的clusterip type,暴露为nodeport。随机分配一个端口31586 ,8000用作集群内访问,随机端口用作公网访问
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.47.0/deploy/static/provider/baremetal/deploy.yaml
#修改镜像
vi deploy.yaml
#将323行的镜像地址改为阿里云镜像地址
image: k8s.gcr.io/ingress-nginx/controller:v0.46.0@sha256:52f0058bed0a17ab0fb35628ba97e8d52b5d32299fbc03cc0f6c7b9ff036b61a
----改为
image: registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/ingress-nginx-controller:v0.46.0
# 检查安装的结果
kubectl get pod,svc -n ingress-nginx
# 最后别忘记把svc暴露的端口要放行
安装完成后
# ingress的安装会产生一个service,ingress要承接所有的流量,
# 所以产生一个service对外暴露承接流量的端口
# 查看svc详细信息
kubectl get svc -A
ingress-nginx ingress-nginx-controller NodePort 10.96.189.29 <none> 80:31735/TCP,443:31607/TCP 88s
# 暴露了http访问的80和https访问的443端口,并随机映射到集群内nodeport端口
# nodeport的端口范围在
30000 - 32767
任意集群服务器的公网IP都能通过这两个端口访问到ingress
官网地址:https://kubernetes.github.io/ingress-nginx/
就是nginx做的
应用如下yaml,准备好测试环境
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-server
spec:
replicas: 2
selector:
matchLabels:
app: hello-server
template:
metadata:
labels:
app: hello-server
spec:
containers:
- name: hello-server
image: registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/hello-server
ports:
- containerPort: 9000
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-demo
name: nginx-demo
spec:
replicas: 2
selector:
matchLabels:
app: nginx-demo
template:
metadata:
labels:
app: nginx-demo
spec:
containers:
- image: nginx
name: nginx
---
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx-demo
name: nginx-demo
spec:
selector:
app: nginx-demo
ports:
- port: 8000
protocol: TCP
targetPort: 80
---
apiVersion: v1
kind: Service
metadata:
labels:
app: hello-server
name: hello-server
spec:
selector:
app: hello-server
ports:
- port: 8000
protocol: TCP
targetPort: 9000
此yml文件的动作为,前两部分为:产生了两个deployment,每个部署了两个pod。
后两部分,产生了两个service,service selector分别选中了之前两次部署的pod,新开端口port映射到pod的端口targetPort,做到负载均衡
deployment :部署的作用是做到pod的自愈
service:作用是负载均衡
添加Ingress的域名访问规则,相当于Spring cloud的GateWay了
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-host-bar
spec:
ingressClassName: nginx
rules:
- host: "hello.atguigu.com"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: hello-server
port:
number: 8000
- host: "demo.atguigu.com"
http:
paths:
- pathType: Prefix
path: "/nginx" # 把请求会转给下面的服务,下面的服务一定要能处理这个路径,不能处理就是404
backend:
service:
name: nginx-demo ## java,比如使用路径重写,去掉前缀nginx
port:
number: 8000
修改本机host文件,因为集群内任意服务器的公网IP都能访问到集群
此时通过
# 查看Ingress的暴露端口来访问Ingress
kubectl get svc -A
http://hello.atguigu.com:31735/
http://demo.atguigu.com:31735/nginx
成功负载均衡的访问到 service下的pod
Ingress的路径重写
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations: # 路径重写
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: ingress-host-bar
spec:
ingressClassName: nginx
rules:
- host: "hello.atguigu.com"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: hello-server
port:
number: 8000
- host: "demo.atguigu.com"
http:
paths:
- pathType: Prefix
path: "/nginx(/|$)(.*)" #(路径重写) 把请求会转给下面的服务,下面的服务一定要能处理这个路径,不能处理就是404
backend:
service:
name: nginx-demo ## java,比如使用路径重写,去掉前缀nginx
port:
number: 8000
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-limit-rate
annotations:
nginx.ingress.kubernetes.io/limit-rps: "1"
spec:
ingressClassName: nginx
rules:
- host: "haha.atguigu.com"
http:
paths:
- pathType: Exact
path: "/"
backend:
service:
name: nginx-demo
port:
number: 8000
Ingress网络模型总结
1、所有节点
#所有机器安装
yum install -y nfs-utils
2、主节点
#nfs主节点暴露/nfs/data/ 目录 *所有人。 非安全、读写
echo "/nfs/data/ *(insecure,rw,sync,no_root_squash)" > /etc/exports
# 主节点创建那个目录
mkdir -p /nfs/data
systemctl enable rpcbind --now
systemctl enable nfs-server --now
#配置生效
exportfs -r
3、从节点
# 查看主节点挂载详情 主节点IP
showmount -e 172.31.0.2
#执行以下命令挂载 nfs 服务器上的共享目录到本机路径 /root/nfsmount
mkdir -p /nfs/data
mount -t nfs 172.31.0.2:/nfs/data /nfs/data
# 写入一个测试文件
echo "hello nfs server" > /nfs/data/test.txt
4、Deployment使用NFS挂载
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-pv-demo
name: nginx-pv-demo
spec:
replicas: 2
selector:
matchLabels:
app: nginx-pv-demo
template:
metadata:
labels:
app: nginx-pv-demo
spec:
containers:
- image: nginx
name: nginx
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
volumes:
- name: html
nfs:
server: 172.31.0.2
path: /nfs/data/nginx-pv
创建时
# 查看容器运行情况
kubectl get pod -A
# 查看容器描述
kubectl describe NAME
发现容器创建错误,没有指定目录,我们删除本次deployment,重新部署。注意先创建挂载目录
PV:持久卷(Persistent Volume),将应用需要持久化的数据保存到指定位置(场地)
PVC:持久卷申明(Persistent Volume Claim),申明需要使用的持久卷规格(场地申明)
PVC会自动合理的选择大小合适的PV
1、创建pv池
#nfs主节点
mkdir -p /nfs/data/01
mkdir -p /nfs/data/02
mkdir -p /nfs/data/03
创建PV
文件分成了三块所以会申明三个pv,
apiVersion: v1
kind: PersistentVolume # 资源类型,pv
metadata:
name: pv01-10m #别名
spec:
capacity:
storage: 10M #限制容量大小
accessModes:
- ReadWriteMany #读写模式 可读、写、多节点
storageClassName: nfs # class别名
nfs:
path: /nfs/data/01
server: 172.31.0.2 # 当前节点地址 master
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv02-1gi
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
storageClassName: nfs
nfs:
path: /nfs/data/02
server: 172.31.0.2
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv03-3gi
spec:
capacity:
storage: 3Gi
accessModes:
- ReadWriteMany
storageClassName: nfs
nfs:
path: /nfs/data/03
server: 172.31.0.2
查看创建情况
kubectl get persistentvolume(pv)
2、PVC创建与绑定
创建pvc
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: nginx-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 200Mi
storageClassName: nfs
实际使用中还是pod不再绑定nfs而是绑定pvc
创建Pod绑定PVC
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-deploy-pvc
name: nginx-deploy-pvc
spec:
replicas: 2
selector:
matchLabels:
app: nginx-deploy-pvc
template:
metadata:
labels:
app: nginx-deploy-pvc
spec:
containers:
- image: nginx
name: nginx
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
volumes: # 这里指定pvc
- name: html
persistentVolumeClaim:
claimName: nginx-pvc
# 修改挂载卷的内容后,进入容器查看内容是否一同变化
kubectl exec -ti nginx-deploy-pvc-79fc8558c7-hmhq2 /bin/bash
抽取应用配置,并且可以自动更新
redis示例
1、把预先创建好的配置文件设置为配置集
# 创建配置,redis保存到k8s的etcd;
kubectl create cm redis-conf --from-file=redis.conf
kubectl get cm redis-conf -oyml
获取到生成的配置文件内容
apiVersion: v1
data: #data是所有真正的数据,key:默认是文件名 value:配置文件的内容
redis.conf: |
appendonly yes
kind: ConfigMap
metadata:
name: redis-conf
namespace: default
2、创建Pod
apiVersion: v1
kind: Pod
metadata:
name: redis
spec:
containers:
- name: redis
image: redis
command:
- redis-server
- "/redis-master/redis.conf" #指的是redis容器内部的位置
ports:
- containerPort: 6379
volumeMounts:
- mountPath: /data
name: data
- mountPath: /redis-master
name: config
volumes:
- name: data
emptyDir: {
}
- name: config
configMap:
name: redis-conf
items:
- key: redis.conf
path: redis.conf
3、检查默认配置
kubectl exec -it redis -- redis-cli
127.0.0.1:6379> CONFIG GET appendonly
127.0.0.1:6379> CONFIG GET requirepass
4、修改ConfigMap
kubectl edit cm redis-conf
apiVersion: v1
kind: ConfigMap
metadata:
name: example-redis-config
data:
redis-config: |
appendonly yes
requirepass 123123
再次检查配置
有些配置需要重启pod才会生效
Secret 对象类型用来保存敏感信息,例如密码、OAuth 令牌和 SSH 密钥。 将这些信息放在 secret 中比放在 Pod 的定义或者 容器镜像 中来说更加安全和灵活。
kubectl create secret docker-registry leifengyang-docker \
--docker-username=leifengyang \
--docker-password=Lfy123456 \
--docker-email=534096094@qq.com
##命令格式
kubectl create secret docker-registry regcred \
--docker-server=<你的镜像仓库服务器> \
--docker-username=<你的用户名> \
--docker-password=<你的密码> \
--docker-email=<你的邮箱地址>
apiVersion: v1
kind: Pod
metadata:
name: private-nginx
spec:
containers:
- name: private-nginx
image: leifengyang/guignginx:v1.0
imagePullSecrets: # 指定存储好的secret
- name: leifengyang-docker