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:

  1. kubelet: API Server 的客户端,与API Server随时通信,接收API Server Scheduler 分发的由自己负责执行的任务
  2. CNI: 容器网络接口 <--> Network Plugins \
  3. CSI: 容器存储接口 <--> Storage Device --》 Pod(Containers|Storage|Network)
  4. CRI: 容器运行时接口 <--> Container Runtime /
  5. 控制器: 负责编排应用
  6. 无状态应用: 通常使用 Deployment
  7. 有状态应用: 通常使用 Statefulset
  8. Service : Pod组织网络的
  9. Ingress : 接入集群外部流量的
  10. 网络:
  11. 节点网络 : 集群当中各个节点通过物理网卡进行通信的叫节点网络
  12. Pod网络 : 一个或多个节点上可以有多个Pod,而Pod之间通信的网络叫Pod网络。Pod之间的网络通信功能K8S没有直接支持,而是委托第三方网络插件来实现的。通过第三方插件实现通信的网络叫做Pod网络。插件有flannel calico canal(前两个的结合)
  13. service网络 : 可以称之为虚拟网络,从本质上讲他并不存,只是出现在iptables ipvs规则当中出现,用于Pod之间通信、以及Pod与外部客户端之间通信时作为流量的管理、整形、地址转换等功能的组件当中使用的。
  14. K8S的三种管理方式:
  15. 命令式命令
  16. 命令式配置文件
  17. 声明式配置文件
  • OCI(Open Container Initiative,开放容器标准)
  • CRI 机制,即容器运行时接口(Container Runtime Interface)

CGroups

image.png

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)

端口映射

  1. root@hyrila:~# docker run -d -it -p 8080:80 nginx

容器多端口映射

  1. root@hyrila:~# docker run -d -it -p 10080:80 -p 10443:443 nginx

启动容器时网络协议默认是TCP协议,如果指定协议的话 “/tcp /udp” “/“ 后跟上协议即可;如下示例:
  1. root@hyrila:~# docker run -d -it -p 10080:80/tcp -p 10443:443/tcp -p 10053:53/udp nginx

查找所有容器并删除
  1. root@hyrila:~# docker rm -fv `docker ps -a -q`

进入容器 docker exec

  1. root@hyrila:~# docker exec -it f2805e476e01 sh

查看容器信息 docker inspect

  1. root@hyrila:~# docker inspect -f "{{.State.Pid}}" f2805e476e01 # 这个是查看容器的PID
  • 这个命令 -f 选项后面要跟 “{{}}” ,括号内以”.”开头,跟上顶级层信息,逐层往后写。比如上面的例子,查看容器PID,PID信息属于顶级State 里的子信息。所以写成”{{.State.Pid}}”
  • 查看容器PID的另一种方式 docker top
    1. root@hyrila:~# docker top f2805e476e01
    2. UID PID PPID C STIME TTY TIME CMD
    3. root 6145 6125 0 17:34 pts/0 00:00:00 /bin/sh
    image.png

    查看和删除 Exited 状态的容器

  1. root@hyrila:~# docker ps -a -f status=exited
  2. root@hyrila:~# docker ps -aq -f status=exited
  3. root@hyrila:~# docker rm -fv `docker ps -aq -f status=exited`

image.png

制作镜像

1. 基于正在运行的容器制作镜像

就是启动一个容器,在容器内安装命令,程序,服务等之后,再提交为一个镜像。这个方式用的很少。优点制作起来方便,缺点是后期想改动的话需要再次跑起来,改完后再提交为容器

  • 下面我启动了centos容器,进去到里面安装了nginx, 并测试把页面修改了一下。然后根据这个容器我生成了新的镜像。
  1. 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

根据容器提交生成镜像image.png

查看生成的镜像并用来启动容器

image.png

  • 检查下效果
    image.png

2. 基于Dockerfile制作镜像

基础镜像==父镜像

EXPOSE : 指令白话概念
  • 在Dockerfile中的 **EXPOSE**指令指出的端口都是该容器启动后容器内的端口。并不是宿主机的端口

ADD : 将宿主机上的文件或目录添加到镜像里面去
  • **ADD** 会对 **tar.gz**的包自动解压,但是相同功能的**COPY**却不会。

ENV :给容器指定全局变量。

3. Nginx 源码编译安装的Dockerfile实战

  1. root@hyrila:/opt/dockerfile/nginx-src# pwd
  2. /opt/dockerfile/nginx-src
  3. root@hyrila:/opt/dockerfile/nginx-src# ls
  4. Dockerfile nginx-1.18.0.tar.gz
  5. root@hyrila:/opt/dockerfile/nginx-src#
  6. root@hyrila:/opt/dockerfile/nginx-src# cat Dockerfile
  7. #
  8. # 用于测试Dockerfile 构建nginx Web静态网站镜像
  9. #
  10. FROM centos:7.7.1908
  11. LABEL maintainer="Wang Xiaoguang < imongol@aliyun.com > or < aiops@qq.com >" # LABEL 是作者信息
  12. RUN yum -y install tree vim telnet net-tools \
  13. && echo "It is a test file." > /root/file.txt \
  14. && yum -y install epel-release \
  15. && yum -y install wget curl lrzsz gcc gcc-c++ \
  16. && yum -y install pcre pcre-devel zlib zliv-devel \
  17. && yum -y install make openssl openssl-devel unzip
  18. ADD nginx-1.18.0.tar.gz /usr/local/src
  19. RUN cd /usr/local/src/nginx-1.18.0 \
  20. && ./configure --prefix=/apps/nginx \
  21. && make && make install \
  22. && rm -rf nginx-1.18.0 \
  23. && ln -s /apps/nginx/sbin/nginx /usr/bin/nginx \
  24. && cd /usr/local/src/ && rm -rf nginx-1.18.0 \
  25. && echo "<h1> Website From Nginx Source Dockerfile Images. </h1>" > /apps/nginx/html/index.html
  26. EXPOSE 80 443 # 容器启动后暴露的端口
  27. CMD ["nginx", "-g", "daemon off;"]
  28. root@hyrila:/opt/dockerfile/nginx-src#

4. 制作centos基础系统镜像

5. 制作JDK镜像

image.png

6. 分层镜像

image.png

7. Dockerfile 优化减少image的大小

image.png

  • 大小对比图

image.png

小架构实验

image.png

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 安全上下文

image.png

拉取镜像策略

image.png

强制删除一个pod
image.png

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

image.png

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

Pod 健康探测

image.png

Pod init 容器

image.png

Pod Sidecar 容器

image.png

Pod 资源限制

image.png

Service

image.png

创建EndPoint

image.png

image.png

Service ClusterIP 通信原理

image.png

Service NodePort 通信原理

image.png

k8s kubectl get 资源对象实时监控状态方法

  1. 1. 使用 '-w' 选项
  2. # kubectl get pods -w
  3. 2. 使用 'watch' 命令: 'watch -n 1' 每一秒看一次
  4. # watch -n 1 kubectl get pods

k8s 滚动升级应用(不停机)

  1. # kubectl set iamge deployment dp-name nginx=nginx:1.18.1 --record
  2. set image : 设置改变 镜像
  3. deployment dp-name : dp-name deployment类型控制器对象
  4. nginx=nginx:1.18.1 : spec.containers.name[value]=spec.containers.image[New_Value]
  5. --record : 记录这次版本的更新

k8s 查看某个资源对象的历史记录

  1. #历史记录
  2. kubectl rollout history deployment/dp-name -n namespace_name

k8s 查看某个历史详情

  1. kubectl rollout history deployment/dp-name --revision=2 # --revision=N

k8s 版本回滚之前的版本

  1. #查看历史变更记录
  2. [root@ip-10-5-1-175 ~]# kubectl rollout history deployment dp-name -n namespace_name
  3. deployment.apps/dp-name
  4. REVISION CHANGE-CAUSE
  5. 1 <none>
  6. 2 <none>
  7. 3 <none>
  8. #回滚(回到上次)
  9. # kubectl rollout undo deployment/my-dep
  10. #回滚(回到指定版本)
  11. # kubectl rollout undo deployment/my-dep --to-revision=2

k8s “rollout” 命令的帮助

  1. [root@ip-10-5-1-175 ~]# kubectl rollout --help
  2. Manage the rollout of a resource.
  3. Valid resource types include:
  4. # * deployments
  5. # * daemonsets
  6. # * statefulsets
  7. Examples:
  8. # Rollback to the previous deployment
  9. # kubectl rollout undo deployment/abc
  10. # Check the rollout status of a daemonset
  11. # kubectl rollout status daemonset/foo
  12. Available Commands:
  13. history View rollout history
  14. pause Mark the provided resource as paused
  15. restart Restart a resource
  16. resume Resume a paused resource
  17. status Show the status of the rollout
  18. undo Undo a previous rollout
  19. Usage:
  20. kubectl rollout SUBCOMMAND [options]
  21. Use "kubectl <command> --help" for more information about a given command.
  22. Use "kubectl options" for a list of global command-line options (applies to all commands).

问:集群内,没有Service的前提下怎么给一个deployment控制器下的一组Pod暴露出来向外提供服务?集群外部访问?

答1:集群内
  1. # kubectl expose deployment my-dp --port=8000 --target-port=80
  2. # 这时候使用kubectl get svc 会发现有一个叫 my-dp 的 service。而这样创建的service默认是ClusterIP类型的

答2: 集群外
  1. # Service如果想对集群外部提供服务访问的话需要创建一个NodePort类型的service,通过--type指定类型
  2. # kubectl expose deployment my-dp --port=8000 --target-port=80 --type=NodePort

**创建的NodePort类型的service,K8S会在每一台Node节点上开启一个随机端口;默认范围是:30000-32767之间**

  1. # kubectl get svc
  2. ...
  3. my-dp NodePort 10.96.91.228 <none> 8000:30948/TCP 28s

image.png

Kubernetes 网络层级关系略图

image.png


kubernetes 卷挂载

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. labels:
  5. app: nginx-pv-demo
  6. name: nginx-pv-demo
  7. spec:
  8. replicas: 2
  9. selector:
  10. matchLabels:
  11. app: nginx-pv-demo
  12. template:
  13. metadata:
  14. labels:
  15. app: nginx-pv-demo
  16. spec:
  17. containers:
  18. - image: nginx:1.21.1
  19. name: nginx
  20. volumeMounts: # 指定容器要挂载卷
  21. - name: html # 定义一个名字,volumes字段配置中需要引用配对。
  22. mountPath: /usr/share/nginx/html # 定义容器内部需要挂载的目录
  23. volumes: # 挂载卷相关的配置清单,是列表形式的,也就是说可以配置多个容器的挂载清单
  24. - name: html #
  25. nfs: # 挂载类型, nfs、 cephfs、AWS EBS等等k8s支持的存储引擎。
  26. server: 172.31.0.4 # nsf server地址
  27. path: /nfs/data/nginx-pv # 外部挂载的目录路径

搭建高可用NFS 同步共享存储集群

环境:三台服务器,一主两从

主:10.1.1.7

从:10.1.1.8、10.1.1.9

1、所有节点创建规划好共享存储路径

  1. mkdir /data/nfs-test

2、所有节点安装nfs-utils

  1. yum install -y nfs-utils

3、主节点配置

  1. echo "/data/nfs-test *(insecure,rw,sync,no_root_squash)" > /etc/exports
  2. systemctl enable rpcbind --now # 设置开机自启同时立即启动(--now)
  3. systemctl enable nfs-server --now
  4. #配置生效
  5. exportfs -r

4、从节点配置

10.1.1.8上

  1. # 检查可挂载的服务节点
  2. showmount -e 10.1.1.7
  3. # 配置共享服务端目录到本地目录,这里是/data/nfs-test(可随意定义)
  4. mount -t nfs 10.1.1.7:/data/nfs-test /data/nfs-test

10.86.33.9上

  1. # 检查可挂载的服务节点
  2. showmount -e 10.1.1.7
  3. # 配置共享服务端目录到本地目录,这里是/data/nfs-test(可随意定义)
  4. mount -t nfs 10.1.1.7:/data/nfs-test /data/nfs-test

5、测试

  1. # 任意一台服务器上
  2. cd /data/nfs-test && mkdir testDir && echo "this is test file" > testDir/test.log
  3. # 其他服务器上检查
  4. ls /data/nfs-test
  5. ls /data/nfs-test/testDir/
  6. cat /data/nfs-test/testDir/test.log
  7. this is test file

kubernetes PV(持久卷)& PVC(持久卷申明)

PV:持久卷

🤔

kubernetes ConfigMap

image.png

kubernetes Secret

Secret 对象类型用来保存敏感信息,例如密码、OAuth 令牌和 SSH 密钥。 将这些信息放在 secret 中比放在 Pod 的定义或者 容器镜像 中来说更加安全和灵活。

k8s 创建镜像仓库的密钥

  1. kubectl create secret docker-registry <your-secret-name> \
  2. --docker-username=<Docker Hub Account Name> \
  3. --docker-password=<Docker Hub Account Password > \
  4. --docker-email=aiops@qq.com
  5. ##命令格式
  6. kubectl create secret docker-registry <Secret-Name-In-k8s> \
  7. --docker-server=<你的镜像仓库服务器> \
  8. --docker-username=<你的用户名> \
  9. --docker-password=<你的密码> \
  10. --docker-email=<你的邮箱地址>

Docker 相关几个命令

  • 正常运行jar包的命令写法:
  1. /usr/lib/jvm/java-1.8-openjdk/bin/java -Xms1024M -Xmx1024M -jar /app.jar
  • 容器内运行java jar包的命令写法:
  1. CMD ["/usr/lib/jvm/java-1.8-openjdk/bin/java","-Xms1024M","-Xmx1024M","-jar","/halo.jar"]
  • docker 打标签:
  1. docker tag SOURCE_IMAGE[:TAG](本地的镜像和版本标签) harbor.yamlops.com/demo/REPOSITORY[:TAG](新命名的镜像仓库路径名称和版本标签)
  • docker 推送:
  1. docker push harbor.yamlops.com/demo/REPOSITORY[:TAG]
  1. 1. 登陆docker
  2. ~ #] docker login harbor.demo.com
  3. Username: admin
  4. Password: (**password)
  5. 2. 打标签
  6. ~ #] docker tag db01cd1d9901 harbor.yamlops.com/demo/halo-api:v5.2.6.38
  7. 3. 推送
  8. ~ #] docker push harbor.yamlops.com/demo/halo-api:v5.2.6.38