- Dockerfile中指令:
- K8S:
- CGroups
- Docker :
- 制作镜像
- 7. Dockerfile 优化减少image的大小
- 小架构实验
- Pod的创建过程
- Kubernetes 网络层级关系略图
- kubernetes 卷挂载
- 搭建高可用NFS 同步共享存储集群
- kubernetes PV(持久卷)& PVC(持久卷申明)
- kubernetes ConfigMap
- kubernetes Secret
Dockerfile中指令:
- FROM : 多阶段构建镜像 需要多用在生产中
- RUN指令 : 是 docker build 的时候运行的命令,可以定义多个RUN,每一个RUN都会运行
- CMD指令 : 是 docker run 的时候运行的命令,不可以定义多个,只会运行最后的一个CMD
- ENTRYPOINT指令 : 是docker run 的时候运行的命令,如果有ENTRYPOINT和CMD同时存在,CMD [“”,””]就成为了为ENTRYPOINT传参数的指令了.ENTRYPOINT无法被覆盖。
- ARG指令 : 是docker build的时候定义的参数
- ENV指令 : 是docker run 的时候定义的环境变量
- ADD指令 : 是将Dockerfile所在的工作目录中文件复制到镜像里 例如:ADD demo-test.py /usr/local/bin/
- EXPOSE : 是定义需要暴露的端口 例如: EXPOSE 80 8080
- VOLUME : 是逻辑卷存储。例如:VOLUME [“/app/data”]
K8S:
kubelet: 是API Server 的客户端,与API Server随时通信,接收API Server 和 Scheduler 分发的由自己负责执行的任务CNI: 容器网络接口 <--> Network Plugins \CSI: 容器存储接口 <--> Storage Device --》 Pod(Containers|Storage|Network)CRI: 容器运行时接口 <--> Container Runtime /控制器: 负责编排应用无状态应用: 通常使用 Deployment有状态应用: 通常使用 StatefulsetService : 为Pod组织网络的Ingress : 接入集群外部流量的网络:节点网络 : 集群当中各个节点通过物理网卡进行通信的叫节点网络Pod网络 : 一个或多个节点上可以有多个Pod,而Pod之间通信的网络叫Pod网络。Pod之间的网络通信功能K8S没有直接支持,而是委托第三方网络插件来实现的。通过第三方插件实现通信的网络叫做Pod网络。插件有flannel calico canal(前两个的结合)service网络 : 可以称之为虚拟网络,从本质上讲他并不存,只是出现在iptables 和 ipvs规则当中出现,用于Pod之间通信、以及Pod与外部客户端之间通信时作为流量的管理、整形、地址转换等功能的组件当中使用的。K8S的三种管理方式:命令式命令命令式配置文件声明式配置文件
- OCI(Open Container Initiative,开放容器标准)
- CRI 机制,即容器运行时接口(Container Runtime Interface)
CGroups

Docker :
容器的几种状态:
- Up: 表示正在运行。可以docker stop ID
Created:被创建之后由于启动参数错误而没有启动成功的。
Exited:已经退出(stop)的容器。这种容器可以删除,也可以docker start ID 。
- paused:被暂停的容器状态
docker ps 只查看正在运行中状态的容器
docker ps -a 查看所有状态的容器
docker ps -a -q 查看所有容器,并把容器ID列出来。
docker pause 容器ID :暂停某个容器。
docker unpause 容器ID:取消暂停。
docker rm 容器 : 删除容器。慎重使用。
docker rm -f 容器:强制删除容器。正在运行的容器也能删除。
docker rm -v 容器: 删除容器时跟着删除关联的卷(volumes)
端口映射
root@hyrila:~# docker run -d -it -p 8080:80 nginx
容器多端口映射
root@hyrila:~# docker run -d -it -p 10080:80 -p 10443:443 nginx
启动容器时网络协议默认是TCP协议,如果指定协议的话 “/tcp /udp” “/“ 后跟上协议即可;如下示例:
root@hyrila:~# docker run -d -it -p 10080:80/tcp -p 10443:443/tcp -p 10053:53/udp nginx
查找所有容器并删除
root@hyrila:~# docker rm -fv `docker ps -a -q`
进入容器 docker exec
root@hyrila:~# docker exec -it f2805e476e01 sh
查看容器信息 docker inspect
root@hyrila:~# docker inspect -f "{{.State.Pid}}" f2805e476e01 # 这个是查看容器的PID
- 这个命令 -f 选项后面要跟 “{{}}” ,括号内以”.”开头,跟上顶级层信息,逐层往后写。比如上面的例子,查看容器PID,PID信息属于顶级State 里的子信息。所以写成”{{.State.Pid}}”
- 查看容器PID的另一种方式 docker top
root@hyrila:~# docker top f2805e476e01UID PID PPID C STIME TTY TIME CMDroot 6145 6125 0 17:34 pts/0 00:00:00 /bin/sh
查看和删除 Exited 状态的容器
root@hyrila:~# docker ps -a -f status=exitedroot@hyrila:~# docker ps -aq -f status=exitedroot@hyrila:~# docker rm -fv `docker ps -aq -f status=exited`

制作镜像
1. 基于正在运行的容器制作镜像
就是启动一个容器,在容器内安装命令,程序,服务等之后,再提交为一个镜像。这个方式用的很少。优点制作起来方便,缺点是后期想改动的话需要再次跑起来,改完后再提交为容器
- 下面我启动了centos容器,进去到里面安装了nginx, 并测试把页面修改了一下。然后根据这个容器我生成了新的镜像。
root@hyrila:~# docker commit -a "WXG IN BJ WorkSpaces" -m "YUM INSTALL NGINX FROM BASE IMAGE CENTOS:7.7.1908" eb8996ca6ad2 centos-ngix:1.01.201204
根据容器提交生成镜像
查看生成的镜像并用来启动容器

- 检查下效果

2. 基于Dockerfile制作镜像
基础镜像==父镜像
EXPOSE : 指令白话概念
- 在Dockerfile中的
**EXPOSE**指令指出的端口都是该容器启动后容器内的端口。并不是宿主机的端口。
ADD : 将宿主机上的文件或目录添加到镜像里面去
**ADD**会对**tar.gz**的包自动解压,但是相同功能的**COPY**却不会。
ENV :给容器指定全局变量。
3. Nginx 源码编译安装的Dockerfile实战
root@hyrila:/opt/dockerfile/nginx-src# pwd/opt/dockerfile/nginx-srcroot@hyrila:/opt/dockerfile/nginx-src# lsDockerfile nginx-1.18.0.tar.gzroot@hyrila:/opt/dockerfile/nginx-src#root@hyrila:/opt/dockerfile/nginx-src# cat Dockerfile## 用于测试Dockerfile 构建nginx Web静态网站镜像#FROM centos:7.7.1908LABEL maintainer="Wang Xiaoguang < imongol@aliyun.com > or < aiops@qq.com >" # LABEL 是作者信息RUN yum -y install tree vim telnet net-tools \&& echo "It is a test file." > /root/file.txt \&& yum -y install epel-release \&& yum -y install wget curl lrzsz gcc gcc-c++ \&& yum -y install pcre pcre-devel zlib zliv-devel \&& yum -y install make openssl openssl-devel unzipADD nginx-1.18.0.tar.gz /usr/local/srcRUN cd /usr/local/src/nginx-1.18.0 \&& ./configure --prefix=/apps/nginx \&& make && make install \&& rm -rf nginx-1.18.0 \&& ln -s /apps/nginx/sbin/nginx /usr/bin/nginx \&& cd /usr/local/src/ && rm -rf nginx-1.18.0 \&& echo "<h1> Website From Nginx Source Dockerfile Images. </h1>" > /apps/nginx/html/index.htmlEXPOSE 80 443 # 容器启动后暴露的端口CMD ["nginx", "-g", "daemon off;"]root@hyrila:/opt/dockerfile/nginx-src#
4. 制作centos基础系统镜像
5. 制作JDK镜像
6. 分层镜像
7. Dockerfile 优化减少image的大小

- 大小对比图
小架构实验
Pod的创建过程
**User Use kubectl Client CMD greate a pod to API Server** **-->** **API Server Write to etcd DB** **-->** **Scheduler Watch ETCD** **-->** **Scheduler See There is Have a New Pod** **-->** **bind pod** **-->** **Scheduler Write bind pod messages to ETCD** **-->** **kubelet client watch API Server** **-->** **kubelet client see the new pod and than bound pod(Get the pod message and than deploy pod on node)** **-->** **kubelet run pod on node** **-->** **kubelet Update Pod status to API Server** **-->** **API Server write pod status to ETCD**
kubectl api-versions : 查看k8s支持的群组和版本信息
kubectl explain Kind_Name(or Kind_Name.ResourceNname…) : 查看资源清单及配置字段
rc : 发行后选版本
Pod 安全上下文

拉取镜像策略

Pod 安全上下文允许设置的安全的sysctl内核参数有三个

- 如果要配置非安全的内核参数的话,需要修改kubelet配置文件,将允许的内核参数加进去。
vim /etc/default/kubelet# /etc/default/kubelet 内容KUBELET_EXTRA_ARGS='--allowed-unsafe-sysctls=参数1,参数2,...'#意思就是允许这些不安全的内核参数在Pod 安全上下文里去设定。# 注意⚠️:每个node 节点都要配置然后重启kubelet哟
Pod 健康探测
Pod init 容器
Pod Sidecar 容器

Pod 资源限制
Service
创建EndPoint


Service ClusterIP 通信原理
Service NodePort 通信原理
k8s kubectl get 资源对象实时监控状态方法
1. 使用 '-w' 选项# kubectl get pods -w2. 使用 'watch' 命令: 'watch -n 1' 每一秒看一次# watch -n 1 kubectl get pods
k8s 滚动升级应用(不停机)
# kubectl set iamge deployment dp-name nginx=nginx:1.18.1 --recordset image : 设置改变 镜像deployment dp-name : 叫dp-name 的 deployment类型控制器对象nginx=nginx:1.18.1 : spec.containers.name[value]=spec.containers.image[New_Value]--record : 记录这次版本的更新
k8s 查看某个资源对象的历史记录
#历史记录kubectl rollout history deployment/dp-name -n namespace_name
k8s 查看某个历史详情
kubectl rollout history deployment/dp-name --revision=2 # --revision=N
k8s 版本回滚之前的版本
#查看历史变更记录[root@ip-10-5-1-175 ~]# kubectl rollout history deployment dp-name -n namespace_namedeployment.apps/dp-nameREVISION CHANGE-CAUSE1 <none>2 <none>3 <none>#回滚(回到上次)# kubectl rollout undo deployment/my-dep#回滚(回到指定版本)# kubectl rollout undo deployment/my-dep --to-revision=2
k8s “rollout” 命令的帮助
[root@ip-10-5-1-175 ~]# kubectl rollout --helpManage the rollout of a resource.Valid resource types include:# * deployments# * daemonsets# * statefulsetsExamples:# Rollback to the previous deployment# kubectl rollout undo deployment/abc# Check the rollout status of a daemonset# kubectl rollout status daemonset/fooAvailable Commands:history View rollout historypause Mark the provided resource as pausedrestart Restart a resourceresume Resume a paused resourcestatus Show the status of the rolloutundo Undo a previous rolloutUsage:kubectl rollout SUBCOMMAND [options]Use "kubectl <command> --help" for more information about a given command.Use "kubectl options" for a list of global command-line options (applies to all commands).
问:集群内,没有Service的前提下怎么给一个deployment控制器下的一组Pod暴露出来向外提供服务?集群外部访问?
答1:集群内
# kubectl expose deployment my-dp --port=8000 --target-port=80# 这时候使用kubectl get svc 会发现有一个叫 my-dp 的 service。而这样创建的service默认是ClusterIP类型的
答2: 集群外
# Service如果想对集群外部提供服务访问的话需要创建一个NodePort类型的service,通过--type指定类型# kubectl expose deployment my-dp --port=8000 --target-port=80 --type=NodePort
**创建的NodePort类型的service,K8S会在每一台Node节点上开启一个随机端口;默认范围是:30000-32767之间**
# kubectl get svc...my-dp NodePort 10.96.91.228 <none> 8000:30948/TCP 28s

Kubernetes 网络层级关系略图

kubernetes 卷挂载
apiVersion: apps/v1kind: Deploymentmetadata:labels:app: nginx-pv-demoname: nginx-pv-demospec:replicas: 2selector:matchLabels:app: nginx-pv-demotemplate:metadata:labels:app: nginx-pv-demospec:containers:- image: nginx:1.21.1name: nginxvolumeMounts: # 指定容器要挂载卷- name: html # 定义一个名字,volumes字段配置中需要引用配对。mountPath: /usr/share/nginx/html # 定义容器内部需要挂载的目录volumes: # 挂载卷相关的配置清单,是列表形式的,也就是说可以配置多个容器的挂载清单- name: html #nfs: # 挂载类型, nfs、 cephfs、AWS EBS等等k8s支持的存储引擎。server: 172.31.0.4 # nsf server地址path: /nfs/data/nginx-pv # 外部挂载的目录路径
搭建高可用NFS 同步共享存储集群
环境:三台服务器,一主两从
主:10.1.1.7
从:10.1.1.8、10.1.1.9
1、所有节点创建规划好共享存储路径
mkdir /data/nfs-test
2、所有节点安装nfs-utils
yum install -y nfs-utils
3、主节点配置
echo "/data/nfs-test *(insecure,rw,sync,no_root_squash)" > /etc/exportssystemctl enable rpcbind --now # 设置开机自启同时立即启动(--now)systemctl enable nfs-server --now#配置生效exportfs -r
4、从节点配置
10.1.1.8上
# 检查可挂载的服务节点showmount -e 10.1.1.7# 配置共享服务端目录到本地目录,这里是/data/nfs-test(可随意定义)mount -t nfs 10.1.1.7:/data/nfs-test /data/nfs-test
10.86.33.9上
# 检查可挂载的服务节点showmount -e 10.1.1.7# 配置共享服务端目录到本地目录,这里是/data/nfs-test(可随意定义)mount -t nfs 10.1.1.7:/data/nfs-test /data/nfs-test
5、测试
# 任意一台服务器上cd /data/nfs-test && mkdir testDir && echo "this is test file" > testDir/test.log# 其他服务器上检查ls /data/nfs-testls /data/nfs-test/testDir/cat /data/nfs-test/testDir/test.logthis is test file
kubernetes PV(持久卷)& PVC(持久卷申明)
PV:持久卷
🤔
kubernetes ConfigMap
kubernetes Secret
Secret 对象类型用来保存敏感信息,例如密码、OAuth 令牌和 SSH 密钥。 将这些信息放在 secret 中比放在 Pod 的定义或者 容器镜像 中来说更加安全和灵活。
k8s 创建镜像仓库的密钥
kubectl create secret docker-registry <your-secret-name> \--docker-username=<Docker Hub Account Name> \--docker-password=<Docker Hub Account Password > \--docker-email=aiops@qq.com##命令格式kubectl create secret docker-registry <Secret-Name-In-k8s> \--docker-server=<你的镜像仓库服务器> \--docker-username=<你的用户名> \--docker-password=<你的密码> \--docker-email=<你的邮箱地址>
Docker 相关几个命令
- 正常运行jar包的命令写法:
/usr/lib/jvm/java-1.8-openjdk/bin/java -Xms1024M -Xmx1024M -jar /app.jar
- 容器内运行java jar包的命令写法:
CMD ["/usr/lib/jvm/java-1.8-openjdk/bin/java","-Xms1024M","-Xmx1024M","-jar","/halo.jar"]
- docker 打标签:
docker tag SOURCE_IMAGE[:TAG](本地的镜像和版本标签) harbor.yamlops.com/demo/REPOSITORY[:TAG](新命名的镜像仓库路径名称和版本标签)
- docker 推送:
docker push harbor.yamlops.com/demo/REPOSITORY[:TAG]
1. 登陆docker~ #] docker login harbor.demo.comUsername: adminPassword: (**password)2. 打标签~ #] docker tag db01cd1d9901 harbor.yamlops.com/demo/halo-api:v5.2.6.383. 推送~ #] docker push harbor.yamlops.com/demo/halo-api:v5.2.6.38

