简易DOCKER/K8S使用心得

2023-11-19

1. DOCKER安装

1.1 前置环境

首先,如果使用CentOS,你至少需要7.4以上。从内核角度来说,建议使用8.2及以上。
如果是7.4以下的版本,可以通过设置仓库到7.4以上版本,再

yum install centos-release kernel
#实际上安装了kernel就可以了,这步可以不做
yum upgrade 

进行版本升级。

此外,还至少需要以下依赖:

yum install -y yum-utils device-mapper-persistent-data lvm2

1.2.docker-ce安装

由于一些众所周知的原因,不能用docker EE,一般建议社区版docker CE

#默认的海外地址,建议用aliyun的加速地址
#yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum install docker-ce -y

1.3. 配置docker

创建或修改此文件 /etc/docker/daemon.json

{
  "registry-mirrors": ["https://xxx.mirror.aliyuncs.com"], //阿里云申请账户时候给的加速地址
  "insecure-registries": ["10.35.9.161"], //可能的私有仓库
  "log-opts": {"max-size":"64m", "max-file":"3"}
}

部分环境存在/etc/systemd/system/docker.service,可能存在–insecure-registries,会发生冲突,删除字段即可。

配置完后即可启动docker

service docker start
docker login registry.cn-hangzhou.aliyuncs.com -u your_account -p your_passwd

2. 生成DOCKER

2.1 简易镜像生成法

首先需要准备一份Dockerfile

FROM hub.docker.com/centos/centos:7.5.1804
COPY myapp/ /opt/myapp/
CMD ["/opt/myapp/start.sh"]

以上述为例,FROM表示基础镜像。
COPY为需要增加文件到DOCKER中的具体位置
CMD为默认命令行

然后就可以生成了

docker build -t hub.my.com/mycomp/myapp:1.0 .

生成完毕后,我们可以上传到仓库当中,注意tag时的version,可以和我们build时不一致;push时需要和tag一致,表示最终上传这个tag。

TAG=`docker images | grep myapp | grep 1.0 | awk {'print $3'} | head -n 1`
docker tag $TAG hub.my.com/mycomp/myapp:1.0
docker push hub.my.com/mycomp/myapp:1.0

2.2 高阶镜像玩法

实际生产过程中,我们可能需要基于标准镜像,准备两份版本。一份包含了完整的编译环境,一份为生产环境运行使用。这样我们就可以在任意部署了docker 的机器上进行三方编译工作,不再依赖编译的宿主机。
以下面的Dockerfile为例,直接用编译镜像生成文件,并直接在生产镜像中应用,制作成运行镜像。

FROM hub.my.com/mycomp/centos78_devel:1.0 AS BUILDS
COPY . /opt/code/mysrc
RUN cd /opt/code/mysrc && ./build.sh

FROM hub.my.com/mycomp/centos78_release:1.0
COPY --from=BUILDS /opt/code/mysrc/dist /opt/myapp
CMD ["/opt/myapp/bin/start_in_docker.sh"]

为了加速源码目录的COPY动作,可以在需要的目录下,设置文件.dockerignore

.svn
**/*.d

2.3 容器的跨仓库迁移

由于实际使用中,生产系统的仓库和开发环境的仓库在物理上并不打通,需要导出成文件方便迁移,常见的有docker save和docker export。关于两者的区别,由详解可知,save不破坏层,更能保持镜像的原汁原味,方便复用,且在基础容器较大的情况下,导出多个容器时反而更节约空间。

开发机上:

docker save hub.my.com/mycomp/myapp:1.0 hub.my.com/mycomp/helloworld:1.0 > 1.tar

生产环境下:

 docker load < 1.tar

3. 调试DOCKER

以上命令表示以HOST模式(直接拥有真机地址)运行镜像。网络模式这里就不展开讨论了。

docker run -it --net=host hub.my.com/mycomp/myapp:1.0
#运行后,可以用ps查看当前正在运行的容器,并通过exec进入该容器
docker ps
docker exec -it 00eeaa6467cc /bin/bash

以下也是一种利用编译镜像编译的办法。
即通过-v参数将本地磁盘的当前路径,映射到docker内的/opt/code目录,并通过-w参数指定该目录为运行目录。
通过-e参数将版本号作为环境变量REVISION,实现自动标记版本号。
和上面的方法的区别在于中间产物会遗留在真实硬盘上,减少复制的成本,方便试错

docker run --rm -it -v $(pwd):/opt/code/ -w /opt/code/ -e REVISION=${REVISION} hub.hitry.io/hitry/centos78_devel:1.0 ./build.sh

4. yaml的一些编写技巧

由于我们是使用了Rancher+K8S的方案,因此对于从机来说,直接按命令运行就行了,K8S的部署就不展开了。
本段开始,都是基于K8S/Rancher来说的。

4.1 活用环境变量的fieldRef

对应在Rancher中就是Field,目前只有这些信息可以获取,复杂的就需要K8SAPI了

名称 含义
metadata.name POD名称,有状态服务时很有用
metadata.namespace 服务命名空间
metadata.uid UID
spec.nodeName 宿主机HostName
spec.serviceAccountName serviceAccount名
status.hostIP 宿主机IP
status.podIP POD IP
status.podIPs POD IP列表

4.2 活用亲和性和反亲和性

4.2.1 利用亲和性设置启动节点

我们可以为每个物理节点打上标签,然后利用亲和性,我们可以指定期望在哪台机器上运行服务。甚至可以结合DaemonSet保证所有的期望节点都跑一遍(虽然不推荐这么干)。

例如:
我们期望最好(可以不是)这个服务在main_node上运行,必须在gpu_node上运行,且不允许在inner_node上运行。如果使用rancher,这个有界面可以配。

spec:
  template:
    spec:
      affinity:
        nodeAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - preference:
              matchExpressions:
              - key: main_node
                operator: In
                values:
                - "true"
            weight: 100
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: gpu_node
                operator: In
                values:
                - "true"
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: inner_node
                operator: NotIn
                values:
                - "true"

4.2.2 利用反亲和性实现应用互斥或最多每机一实例

在rancher中并不提供反亲和性的图形化配置,不过可以手工修改yaml支持此K8S的特性
比较典型的一个应用场景是我希望某个服务(特别是网络类型为HOST模式的)最多每台机器起一份,避免端口冲突,或GPU使用冲突。

以流媒体服务为例,其存在大范围UDP端口段监听,必然使用HOST模式。我也不需要使用DaemonSet方式每机起一份加大问题定位的复杂度,可能只需要双机热备,或按需扩容。因此,正常使用时,只要保证运行的实例数量小于节点数量即可;但是当部分节点瘫痪,使得实例数大于节点数时,就需要阻塞那些多出来的实例,把他们挂起,不要拥挤到同一台机器跑起来。

此时可以这样处理:

  1. 为该服务分配一个标签,key为app,value为mediasvr
spec:
  template:
    metadata:
      labels:
        app: mediasvr
  1. 设置反亲和性,不允许在已经有app=mediasvr标签的机器上运行(不同的服务都设置key=app,是并行存在的,如果你想A服务和B服务互斥,也可以用相同的办法)
spec:
  template:
    spec:
      affinity:
		podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - mediasvr
            topologyKey: kubernetes.io/hostname

5. K8SAPI

在某些情况下,我们需要更为复杂的操作,可以使用K8S的API进行复杂查询

K8S API v1.20

调用K8S的API需要的token,基本有两种方法:

  1. 使用你本身的serviceaccount进行查询。但是需要注意的是默认的default账户权限很低,很多操作需要自定义账户并提权。
  2. 可以创建一个公用的API Key,并将Bearer Token保存下来(比方说放置到config map中,让具体的服务通过环境变量引用得知)。在rancher中,操作流程为:
    在这里插入图片描述
    “右上角下拉”-> “API & Keys” -> “添加Key”-> “选择作用范围到指定集群”
    *注意:不选择作用范围,这个key只能调用rancher的API,选择了集群,则会自动在K8S中创建账户

5.1 利用K8S API 获取所有节点的IP列表

举个实际的例子,当一个HOST类型的服务,启动了某个内部通讯用的监听,我并不想让外部来连接,需要一个IP白名单。在传统的方案中,只能依靠部署人员手工配置,或者直接网络隔离(防火墙/NAT等)。
利用K8S的API,我们可以轻易的得知所有服务节点清单,以配置白名单。

curl -H "Authorization: Bearer $token" -X GET -H 'Accept: application/json' -H 'Content-Type: application/json' --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt https://127.0.0.1:6443/api/v1/nodes > nodes.json

需要注意的事项:
1)$token就是上面说的Bearer Token
2)如果不是HOST模式,那么请求的地址就不能是127.0.0.1,而是上面提到的status.hostIP中获取到的宿主机IP。
3)CA证书可以不指定,设置成允许非安全连接也能用。

此时拿到的是一个很长的json。我们可以使用一个简易的Python或者其他语言来解析他。

python fetch_ip.py nodes.json > whitelist.conf
#!/usrbin/env python

import json
import string
import httplib,sys

if __name__ == '__main__' :
    if len( sys.argv ) < 2 :
        print "Please run like this: python fetch_ip.py <filePath>"

    f = open(sys.argv[1],'r');
    rootnode = json.load(f)
    for item in rootnode["items"]:
        for addr in item["status"]["addresses"]:
            if addr["type"] == "InternalIP":
                print addr["address"]

5.2 利用K8S API 获取指定服务的POD列表

还是以之前的mediasvr为例。当某些场景下,我希望获取所有的mediasvr清单。
可以利用设置标签+labelSelector进行筛选。本质上来说你找的是拥有这个标签的POD,不是这个服务名的。

curl -H "Authorization: Bearer $token" -X GET -H 'Accept: application/json' -H 'Content-Type: application/json' --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt https://127.0.0.1:6443/api/v1/namespaces/default/pods?labelSelector=app%3Dmediasvr
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

简易DOCKER/K8S使用心得 的相关文章

随机推荐

  • Springboot自动装配原理详解

    Springboot自动装配原理 主程序类 主入口类 SpringBootApplication public class MysteelEnglishWebApplication public static void main Strin
  • 怎么通过SPSS的神经网络模型预测结果

    神经网络模型是数据分析常用的模型 它广泛应用于众多领域 比如 医疗 人工智能 深度学习 语音 机器人等 它能通过现有数据经过神经网络模型训练得到训练模型 再将模型运用于预测数据集 进而得到预测结果 并且将预测趋势应用于各个领域 IBM SP
  • 元字符的详细解析

    上一篇文章介绍了正则的用处以及正则中这些元字符的基本含义 但是如果我们只知道那些元字符的含义 不知道怎么使用和加以练习 那么对于正则我们还只是看见了门槛 并没有踏入 那么本篇文章就让我们迈起脚步正式走入正则的世界吧 let s go 我的学
  • 714阿里巴巴模拟面试

    介绍一下数据库分页 https www nowcoder com questionTerminal 3577280c810546658f06f19c01ff0345 给定一棵树 求出这棵树的直径 即两个节点距离的最大值 应该是左右子树遍历深
  • Combox的GetLBText();遇到的问题和解决方法

    最近有个项目要结束但是测试的时候发现一个问题 就是点击Combox的时候偶尔出现程序卡死 找了半天最后定位到GetLBText 的函数上 发现当你在选择索引或者Combox获得焦点的时候GetLBText都会执行到 正常的值肯定没有我问题
  • linux下安装awk

    sudo apt get install gawk 注意名称
  • Linux环境下 通过V4L2读取视频+UDP发送图片文件

    该图为整个项目的流程图 其中左边的流程为总流程 包括通过中断读取摄像头的帧数据 通过内存映射将内核态的数据映射到用户态 读取用户态的数据 采用循环发送图片数据 右边是发送图片的流程图 将用户态的缓冲区的数据通过内存映射到用户态 通过内存拷贝
  • java学习记录之JVM篇

    垃圾标记 gt 根可达 垃圾回收算法 复制算法 标记清除 标记整理 普通GC Minor GC 只针对新生代 新生代对象大多存活不高 垃圾回收频繁 回收速度较快 Full GC 全局gc 针对老年代 可能会伴随普通gc 速度较慢 回收算法有
  • window系统消失的c盘,实际占用与显示占用相差好多G

    问题 C盘一直显示的红色提醒 我c盘实际占用的空间只有33 1GB 而我的c盘总共大小是59 9GB 显示的剩余大小是1 35GB 也就是说我占用了58 11 和c盘的总文件大小相差了25GB 那么消失的25GB去了哪里 我百度过这个问题
  • 如何用微信自动添加wifi连接服务器地址,微信服务号如何实现扫码自动连接WIFI?详细步骤介绍!...

    微信服务号如何实现扫码自动连接WIFI 详细步骤介绍 有的朋友在运营这个微信公众号的时候 会想着如果有更多人关注自己的运营号就好了 但有的朋友没有找到好的办法 不知道如何吸引更多人的关注 下面小编给大家提供一个思路 就是当大家在关注微信公众
  • 移动端证件识别OCR

    证件识别利用的是ocr识别原理 也就是光学字符识别 证件识别方法有很多 先说第一种 用一个读港澳通行证的仪器就行 而且连上系统还能直接把信息导出成EXCEL文档 其实这个仪器叫做证件识别仪 可以识别护照 港澳通行证 台胞证 身份证 驾驶证
  • python pyplot logscale 画图对数

    原文来自公众号 工程师看海 事情的起因是我要在公众号 工程师看海 更新一篇文章 介绍电感 磁珠的区别 需要画阻抗 频率曲线 横坐标频率要按照log对数尺度缩放 就写了python代码 废话不多说 先看结果 公众号后台回复 python lo
  • 【Xilinx DDR3 MIG】Xilinx FPGA DDR3读写实验相关用户接口引脚解释

    目录 DDR3读写实验 实验框图 时钟模块 DDR3读写及LED指示模块 MIG IP核 用户接口解释
  • Python自定义异常 Python Custom Exception

    个人主页 Aurora 如果文章有什么需要改进的地方还请各位大佬指正 如果我的文章对你有帮助 关注 点赞 收藏 一 python自定义异常 1 自定义一个CustomException类 继承Exception类 2 编写CustomExc
  • cur.execute(sql,args)和cur.execute(sql)的区别

    python代码示例 方式一 userid 123 sql select id name from user where id s userid cur execute sql 方式二 sql语句模板中的参数填充符是 s 而不是 s 且多个
  • Linux上开发常见问题整理

    Linux上开发常见问题整理 1 java工程在linux上运行测试 首先要有一个main方法作为主类 程序的入口 右键 gt Run As gt javaapplication生成配置文件入口 右键该工程 gt Export gt Run
  • LaTeX 多行公式、公式对齐以及输入矩阵的方法

    一 LaTex显示 大括号连接的 多行公式 公式组合 使用cases环境实现公式的组合 分隔公式和条件 具体LaTex代码如下 D x begin cases lim limits x to 0 frac a x b c x lt 3 pi
  • tshark 解析pcap中带TLS协议的数据包

    tshark的简单用法参考 tshark解析本地pcap数据包提取五元组 src ip src port proto dst ip dst port 与时间戳 包长 详细用法 官方DOC 比如提取一个数据包 my pcap 中全部带有TLS
  • Oracle数据恢复:强制Resetlogs的可能数据损失

    Oracle数据恢复 强制Resetlogs的可能数据损失 Oracle数据恢复 格式化 ASM及字典损坏案例三则 ORA 00600 kcratr nab less than odr案例一则 SMON recover undo segme
  • 简易DOCKER/K8S使用心得

    1 DOCKER安装 1 1 前置环境 首先 如果使用CentOS 你至少需要7 4以上 从内核角度来说 建议使用8 2及以上 如果是7 4以下的版本 可以通过设置仓库到7 4以上版本 再 yum install centos releas