一、Python 应用案例环境

[root@k8s-node1 Flask]# pwd
/opt/Dockerfile/Flask
[root@k8s-node1 Flask]# ll
total 12
-rw-r--r-- 1 root root 352 Feb 1 10:08 app.py
-rw-r--r-- 1 root root 518 Feb 1 10:20 Dockerfile
-rw-r--r-- 1 root root 6 Feb 1 10:09 requirements.txt
[root@k8s-node1 Flask]# cat app.py
from flask import Flask
import socket
import os app = Flask(__name__) @app.route('/')
def hello():
html = "<h3>Hello {name}!</h3>" \
"<b>Hostname:</b> {hostname}<br/>"
return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname()) if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)
[root@k8s-node1 Flask]# cat requirements.txt
Flask
[root@k8s-node1 Flask]# cat Dockerfile
# 使用官方提供的 Python 开发镜像作为基础镜像
FROM python:2.7-slim # 将工作目录切换为 /app
WORKDIR /app # 将当前目录下的所有内容复制到 /app 下
ADD . /app # 使用 pip 命令安装这个应用所需要的依赖
RUN pip install --trusted-host pypi.python.org -r requirements.txt # 允许外界访问容器的 80 端口
EXPOSE 80 # 设置环境变量
ENV NAME World # 设置容器进程为:python app.py,即:这个 Python 应用的启动命令
CMD ["python", "app.py"]

Dockerfile的设计思想,是使用一些标准的原语(即大写高亮的词语),描述我们所要构建的Docker镜像,并且这些原语,都是按顺序处理的

需要注意的是,Dockerfile中的每个原语执行后,都会生成一个对应的镜像层

[root@k8s-node1 Flask]# docker images|grep docker.io/python
docker.io/python

二、启动容器以及相关操作

1、启动容器

$ docker run -p 4000:80 helloworld

2、查看进程

$ docker ps
CONTAINER ID IMAGE COMMAND CREATED
4ddf4638572d helloworld "python app.py" 10 seconds ago

3、测试是否可用

$ curl http://localhost:4000
<h3>Hello World!</h3><b>Hostname:</b> 4ddf4638572d<br/>

4、上传镜像到仓库

[root@k8s-node1 ~]# docker exec -it 900e7b6e1984 /bin/sh#
# touch test.txt#
# exit#
[root@k8s-node1 ~]# docker tag helloworld 10.0.128.4:500/helloworld:v1#
[root@k8s-node1 ~]# docker push 10.0.128.4:500/helloworld:v1#
The push refers to a repository [10.0.128.4:500/helloworld]#
Get https://10.0.128.4:500/v1/_ping: dial tcp 10.0.128.4:500: getsockopt: connection refused "/bin/sh" 2 days ago Exited (137) 2 days ago grave_mclean#

三、docker exec 是怎么做到进入容器里的呢?

1、docker exec 的实现原理

[root@k8s-node1 Flask]# docker exec -it 43c49903582e /bin/sh
# pwd
/app
# ls
Dockerfile app.py requirements.txt test.txt

这里,我使用了docker exec 命令进入到了容器当中,在了解了Linux Namespace的隔离机制后,你应该会很自然地想到一个问题
docker exec 是怎么做到进入容器里的呢?

[root@k8s-node1 Flask]# docker inspect --format '{{ .State.Pid }}' 43c49903582e
2400
[root@k8s-node1 opt]# ls -l /proc/2400/ns
total 0
lrwxrwxrwx 1 root root 0 Feb 20 17:20 ipc -> ipc:[4026532495]
lrwxrwxrwx 1 root root 0 Feb 20 17:19 mnt -> mnt:[4026532493]
lrwxrwxrwx 1 root root 0 Feb 20 17:19 net -> net:[4026532498]
lrwxrwxrwx 1 root root 0 Feb 20 17:20 pid -> pid:[4026532496]
lrwxrwxrwx 1 root root 0 Feb 20 17:23 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 Feb 20 17:20 uts -> uts:[4026532494]

这也就意味着:一个进程,可以选择加入到某个进程已有的 Namespace 当中,从而达到“进入”这个进程所在容器的目的,这正是 docker exec 的实现原理

2、docker exec 的实现原理刨析实验

1、依赖文件

_startmainopen@@GLIBC_2.2.5perror@@GLIBC_2.2.5_Jv_RegisterClassesexecvp@@GLIBC_2.2.5exit@@GLIBC_2.2.5__TMC_END___ITM_registerTMCloneTable_init
[root@k8s-node1 opt]# cat set_ns.c
#define _GNU_SOURCE
#include <fcntl.h>
#include <sched.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h> #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE);} while (0) int main(int argc, char *argv[]) {
int fd; fd = open(argv[1], O_RDONLY);
if (setns(fd, 0) == -1) {
errExit("setns");
}
execvp(argv[2], &argv[2]);
errExit("execvp");
}

2、执行

[root@k8s-node1 opt]# gcc -o set_ns set_ns.c
[root@k8s-node1 opt]# ./set_ns /proc/2400/ns/net /bin/bash
[root@k8s-node1 opt]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.16.6.2 netmask 255.255.255.0 broadcast 0.0.0.0
inet6 fe80::42:acff:fe10:602 prefixlen 64 scopeid 0x20<link>
ether 02:42:ac:10:06:02 txqueuelen 0 (Ethernet)
RX packets 8 bytes 648 (648.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 648 (648.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

3、查看进程的进程的 Namespace

[root@k8s-node1 opt]# ps aux|grep /bin/bash
root 2615 0.1 0.0 116204 2876 pts/0 S 17:28 0:00 /bin/bash
root 2652 0.0 0.0 112660 972 pts/0 R+ 17:28 0:00 grep --color=auto /bin/bash
[root@k8s-node1 opt]# ls -l /proc/2615/ns/net
lrwxrwxrwx 1 root root 0 Feb 20 17:30 /proc/2615/ns/net -> net:[4026532498]
[root@k8s-node1 opt]# ls -l /proc/2400/ns/net
lrwxrwxrwx 1 root root 0 Feb 20 17:19 /proc/2400/ns/net -> net:[4026532498]

转了一个大圈子,我其实是为你详细解读了这个操作背后,linux namespace更具体的工作原理

这种通过操作系统进程相关的知识,逐步刨析Docker容器的方法,是理解容器的一个关键思路,希望你一定要掌握

深入剖析Kubernetes学习笔记:深入理解镜像(08)的更多相关文章

  1. 深入剖析Kubernetes学习笔记:深入理解镜像(07)

    一.容器里的进程看到的文件系统又是什么样子呢? 1.你会看到好多宿主机的文件 [root@k8s-master ~]# vim ns.c [root@k8s-master ~]# gcc -o nl ...

  2. 深入剖析Kubernetes学习笔记:开篇词(00)

    一.关于Kubernetes初学的疑惑 就在这场因"容器"而起的技术变革中,kubernetes项目已经成为容器技术的事实标准,重新定义了基础设置领域对应用编排与管理的种种可能 1 ...

  3. 深入剖析Kubernetes学习笔记:预习篇(01-04)

    01 初出茅庐 1.PaaS 项目被大家接纳的一个主要原因? 就是它提供了一种名叫"应用托管". 2.像 Cloud Foundry 这样的 PaaS 项目,最核心的组件是? 一套 ...

  4. 深入剖析Kubernetes学习笔记:容器基础(05-06)

    05 :从进程说起 1.容器本身没有价值,有价值的是"容器编排" 2.什么是进程? 一旦"程序"被执行起来,它就从磁盘上的二进制文件,变成 1.计算机内存中的数 ...

  5. Kubernetes 学习笔记(一):基础概念

    个人笔记,仅本人查阅使用,不保证正确. 零.微服务 微服务架构专注于应用解耦合,通过将应用彻底地组件化和服务化,每个微服务只包含一个非常小的功能,比如权限管理.日志收集等等.由这一组微服务组合起来,提 ...

  6. Kubernetes学习笔记(八):Deployment--声明式的升级应用

    概述 本文核心问题是:如何升级应用. 对于Pod的更新有两种策略: 一是删除全部旧Pod之后再创建新Pod.好处是,同一时间只会有一个版本的应用存在:缺点是,应用有一段时间不可用. 二是先创建新Pod ...

  7. 微信小程序开发:学习笔记[7]——理解小程序的宿主环境

    微信小程序开发:学习笔记[7]——理解小程序的宿主环境 渲染层与逻辑层 小程序的运行环境分成渲染层和逻辑层. 程序构造器

  8. Kubernetes学习笔记(四):服务

    服务介绍 服务是一种为一组相同功能的pod提供单一不变接入点的资源.当服务存在时,他的IP和端口不会改变.客户端通过IP和端口建立连接,这些连接会被路由到任何一个pod上.如此,客户端不需要知道每个单 ...

  9. Kubernetes学习笔记之认识Kubernetes组件

    前言:笔记知识点来源于Kubernetes官方文档说明,链接:https://kubernetes.io/docs/concepts/overview/components/ ,本记录仅仅是学习笔记记 ...

随机推荐

  1. 南邮攻防训练平台逆向maze

    文件为 ELF64 可执行文件,输入正确 flag 返回判定结果的逆向题. 用 ida 打开,先看f5之后的代码,容易知道 flag 长度为24位,以 "nctf{" 为前缀: 先 ...

  2. Kafka 安装配置 windows 下

    Kafka 安装配置 windows 下 标签(空格分隔): Kafka Kafka 内核部分需要安装jdk, zookeeper. 安装JDK 安装JDK就不需要讲解了,安装完配置下JAVA_HOM ...

  3. 腾讯大数据平台Oceanus: A one-stop platform for real time stream processing powered by Apache Flink

    January 25, 2019Use Cases, Apache Flink The Big Data Team at Tencent     In recent years, the increa ...

  4. Centos安装php php-fpm 以及 配置nginx

    下载php源码包 http://www.php.net/downloads.php 安装php .tar.bz2 cd php- ./configure --prefix=/usr/local/php ...

  5. MySQL常用日期时间函数

    日期和时间函数: MySQL服务器中的三种时区设置: ①系统时区---保存在系统变量system_time_zone ②服务器时区---保存在全局系统变量global.time_zone ③每个客户端 ...

  6. Linux内存管理 (2)页表的映射过程

    专题:Linux内存管理专题 关键词:swapper_pd_dir.ARM PGD/PTE.Linux PGD/PTE.pgd_offset_k. Linux下的页表映射分为两种,一是Linux自身的 ...

  7. Golang 入门系列(七) Redis的使用

    安装 1. Redis 的安装很简单,我这里测试直接用的是windows 的版本.如何安装就不细说了.想了解的可以看之前的文章:https://www.cnblogs.com/zhangweizhon ...

  8. Dubbo-Zookeeper安装

    安装zookeeper: 1.拖入tar.gz包,解压 2.建立/usr/zookeeper路径,该路径创建logs文件夹和data文件夹 3.进入conf目录,复制一份zoo_sample.cfg为 ...

  9. linkedin 第三方网站登录(JavaScript SDK)

    官网:https://developer.linkedin.com/docs/oauth2 一.配置LinkedIn应用程序 a.创建一个应用  |  https://www.linkedin.com ...

  10. .NET Core 开源工具 IPTools - 快速查询 IP 地理位置、经纬度信息

    快速查询IP信息,支持国内和国外IP信息查询,支持查询经纬度,地理位置最高支持到城市. 1. IPTools.China 快速查询中国IP地址信息,包含国家.省份.城市.和网络运营商.非中国IP只支持 ...