- 云平台
- 私有网络VPC
- VPC的子网计算
- VPC的交换机
- 重要概念
- 容器化
- docker概念
- 青云服务器
- centos安装docker
- docker实战
- docker进阶
- 部署redis
- 创建Java应用
- Kubernetes
- 基础概念
- 简介
- 集群的方式
- 集群搭建
- 创建服务器
- docker容器化环境安装
- 预备环境创建
- 安装集群三大件
- 使用kubeadm引导启动集群
- 部署dashboard
- 核心实战
- 操作NameSpace
- 理解Pod
- 可视化方式操作pod和pod细节
- 使用Deployment部署应用
- Deployment扩缩容
- 自愈&故障转移
- 服务网络
- Ingress
- Ingress的使用
- 存储抽象
- 环境准备
- PV&PVC
- ConfigMap
- Secret
- end
简介:摘自 尚硅谷雷锋阳老师的语雀文档
云平台学会使用按量付费的云服务器,开发测试性价比高
私有网络VPC和网络有关的概念,如何在云服务器开通一个集群
一个云服务器有两个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个
VPC的交换机因为专有网络的可用IP太多了不好区分,单16位掩码的IP就有65534个,所以交换机的作用是用来规定专有网络下的哪些IP能用,避免专有网络使用太过混乱
在创建专有网络时同时制定或创建交换机,如下图的设定,表示创建24位掩码,指定第三段的号段,那么可用IP就在第4号段变化,将可用IP由65534个缩小到了252个,避免了混乱
不同VPC网络下,即使私有网络IP相同,他们之间内部是无法平通的,所以一个VPC相当于一个局域网的隔离,
容器化 docker概念差异化保存
资源隔离
● cpu、memory资源隔离与限制
● 访问设备隔离与限制
● 网络隔离与限制
● 用户、用户组隔离限制
架构
- Docker_Host:
○ 安装Docker的主机 - Docker Daemon:
○ 运行在Docker主机上的Docker后台进程 - Client:
○ 操作Docker主机的客户端(命令行、UI等) - Registry:
○ 镜像仓库
○ Docker Hub - Images:
○ 镜像,带环境打包好的程序,可以直接启动运行 - Containers:
○ 容器,由镜像启动起来正在运行中的程序
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
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.confdocker进阶 部署redis
部署一个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创建Java应用
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为例
- SpringBoot打包成可执行jar
- 把jar包上传给服务
- 服务器运行java -jar
现在:所有机器都安装Docker,任何应用都是镜像,所有机器都可以运行
3、怎么打包-Dockerfile
FROM openjdk:8-jdk-slim #基础运行环境,相当去掉了 duoker pull LABEL maintainer=leifengyang #作者 COPY target#&/' /etc/fstab #允许 iptables 检查桥接流量 cat <安装集群三大件 安装kubelet、kubeadm、kubectl
# 设置镜像源 cat <使用kubeadm引导启动集群 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.sh2、初始化主节点
#所有机器添加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 -A3、安装网络组件
curl https://docs.projectcalico.org/manifests/calico.yaml -O kubectl apply -f calico.yaml4、加入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部署dashboard83s v1.20.9 k8s-node2 Ready 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
将type的值改为NodePortkubectl 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-dashboardkubectl apply -f dash.yaml4、令牌访问
#获取访问令牌 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}}"复制返回的密钥就能登录
核心实战 操作NameSpace名称空间用来对资源隔离划分。默认只隔离资源,不隔离网络
创建删除名称空间
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运行中的一组容器,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: mynginxkubectl apply -f 配置文件 kubectl delete -f 配置文件可视化方式操作pod和pod细节
可视化控制台直接查看容器日志,和进入容器的内部相当于 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使用Deployment部署应用
此时的应用还不能外部访问,只能内部互相调用控制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=3apiVersion: 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查看部署
Deployment扩缩容
kubectl get deploy xxxxkubectl scale --replicas=5 deployment/my-dep自愈&故障转移启动了一个deployment有三个容器部署,其中node2两个,node1一个
我们关机node2服务器,集群默认5分钟后才会做故障转移工作
# 查看pod详细信息 kubectl get pod -owide # 监控pod kubectl get pod -w4、滚动更新
不停机更新,更改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-dep5、版本回退
#历史记录 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=ClusterIP2、NodePort
kubectl expose deployment my-dep --port=8000 --target-port=80 --type=NodePort先删除之前的clusterip type,暴露为nodeport。随机分配一个端口31586 ,8000用作集群内访问,随机端口用作公网访问
Ingress
1、安装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.2980:31735/TCP,443:31607/TCP 88s # 暴露了http访问的80和https访问的443端口,并随机映射到集群内nodeport端口 # nodeport的端口范围在 30000 - 32767 任意集群服务器的公网IP都能通过这两个端口访问到ingress
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: 8000apiVersion: 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: 8000Ingress网络模型总结
存储抽象 环境准备1、所有节点
#所有机器安装 yum install -y nfs-utils2、主节点
#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 -r3、从节点
# 查看主节点挂载详情 主节点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.txt4、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&PVCPV:持久卷(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创建与绑定
创建pvckind: PersistentVolumeClaim apiVersion: v1 metadata: name: nginx-pvc spec: accessModes: - ReadWriteMany resources: requests: storage: 200Mi storageClassName: nfs实际使用中还是pod不再绑定nfs而是绑定pvc
创建Pod绑定PVCapiVersion: 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/bashConfigMap抽取应用配置,并且可以自动更新
redis示例
1、把预先创建好的配置文件设置为配置集
# 创建配置,redis保存到k8s的etcd; kubectl create cm redis-conf --from-file=redis.confkubectl get cm redis-conf -oyml
获取到生成的配置文件内容apiVersion: v1 data: #data是所有真正的数据,key:默认是文件名 value:配置文件的内容 redis.conf: | appendonly yes kind: ConfigMap metadata: name: redis-conf namespace: default2、创建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.conf3、检查默认配置
kubectl exec -it redis -- redis-cli 127.0.0.1:6379> ConFIG GET appendonly 127.0.0.1:6379> ConFIG GET requirepass4、修改ConfigMap
kubectl edit cm redis-conf
apiVersion: v1 kind: ConfigMap metadata: name: example-redis-config data: redis-config: | appendonly yes requirepass 123123再次检查配置
Secret
有些配置需要重启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-dockerend



