如何在ARM上运行k3s? 窥探k3s启动过程!,内附容器多平台包构建
开始之前
最近在对华为云鲲鹏服务器(一种ARM服务器arm64)运行容器可行性做验证,顺便了解了很多ARM和容器相关的知识。一提到arm运行容器首先想到的是k3s,下面是用k3s快速搭建一个kubernetes系统,运行arm的镜像的案例。
环境准备
arm的环境想到最多的估计就是树莓派,这玩意儿平常用的比较少,成本还是相对比较高,要玩arm的环境推荐华为云的鲲鹏服务器。
环境准备:
- 通过华为云购买一台2u4g的鲲鹏服务器。
- 安装欧拉(一种类似CentOS的系统, openEuler)系统
- 下载k3s-arm64程序(不建议k3s-install.sh安装主要是墙的问题)
节点准备
由于k3s需要使用iptable相关功能,所以需要对系统进行设置,配置方法如下(自行转化):
---
- name: Set SELinux to disabled state
selinux:
state: disabled
when: ansible_distribution in ['CentOS', 'Red Hat Enterprise Linux']
- name: Enable IPv4 forwarding
sysctl:
name: net.ipv4.ip_forward
value: "1"
state: present
reload: yes
- name: Enable IPv6 forwarding
sysctl:
name: net.ipv6.conf.all.forwarding
value: "1"
state: present
reload: yes
- name: Add br_netfilter to /etc/modules-load.d/
copy:
content: "br_netfilter"
dest: /etc/modules-load.d/br_netfilter.conf
when: ansible_distribution in ['CentOS', 'Red Hat Enterprise Linux']
- name: Load br_netfilter
modprobe:
name: br_netfilter
state: present
when: ansible_distribution in ['CentOS', 'Red Hat Enterprise Linux']
- name: Set bridge-nf-call-iptables (just to be sure)
sysctl:
name: "{{ item }}"
value: "1"
state: present
reload: yes
when: ansible_distribution in ['CentOS', 'Red Hat Enterprise Linux']
loop:
- net.bridge.bridge-nf-call-iptables
- net.bridge.bridge-nf-call-ip6tables
- name: Add /usr/local/bin to sudo secure_path
lineinfile:
line: 'Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin'
regexp: "Defaults(\\s)*secure_path(\\s)*="
state: present
insertafter: EOF
path: /etc/sudoers
validate: 'visudo -cf %s'
when: ansible_distribution in ['CentOS', 'Red Hat Enterprise Linux']
文件来源: k3s-ansible/roles/prereq/tasks/main.yml
启动k3s,观察启动过程
这个步骤很简单,直接上命令
./k3s-arm64 server --disable traefik
来观察启动日志
- 启动api-server
INFO[2020-05-26T19:06:51.465258246+08:00] Starting k3s v1.18.2+k3s1 (698e444a)
INFO[2020-05-26T19:06:51.482543936+08:00] Kine listening on unix://kine.sock
INFO[2020-05-26T19:06:51.686990438+08:00] Active TLS secret (ver=) (count 7): map[listener.cattle.io/cn-10.43.0.1:10.43.0.1 listener.cattle.io/cn-127.0.0.1:127.0.0.1 listener.cattl
e.io/cn-172.27.16.180:172.27.16.180 listener.cattle.io/cn-kubernetes:kubernetes listener.cattle.io/cn-kubernetes.default:kubernetes.default listener.cattle.io/cn-kubernetes.default.
svc.cluster.local:kubernetes.default.svc.cluster.local listener.cattle.io/cn-localhost:localhost listener.cattle.io/hash:b3257e2631debdf2681f1c0f10956c55d518909c88e3581e6a5d97562ab0
fabf]
INFO[2020-05-26T19:06:51.691943011+08:00] Running kube-apiserver --advertise-port=6443 --allow-privileged=true --anonymous-auth=false --api-audiences=unknown --authorization-mode=No
de,RBAC --basic-auth-file=/var/lib/rancher/k3s/server/cred/passwd --bind-address=127.0.0.1 --cert-dir=/var/lib/rancher/k3s/server/tls/temporary-certs --client-ca-file=/var/lib/ranch
er/k3s/server/tls/client-ca.crt --enable-admission-plugins=NodeRestriction --etcd-servers=unix://kine.sock --insecure-port=0 --kubelet-certificate-authority=/var/lib/rancher/k3s/ser
ver/tls/server-ca.crt --kubelet-client-certificate=/var/lib/rancher/k3s/server/tls/client-kube-apiserver.crt --kubelet-client-key=/var/lib/rancher/k3s/server/tls/client-kube-apiserv
er.key --proxy-client-cert-file=/var/lib/rancher/k3s/server/tls/client-auth-proxy.crt --proxy-client-key-file=/var/lib/rancher/k3s/server/tls/client-auth-proxy.key --requestheader-a
llowed-names=system:auth-proxy --requestheader-client-ca-file=/var/lib/rancher/k3s/server/tls/request-header-ca.crt --requestheader-extra-headers-prefix=X-Remote-Extra- --requesthea
der-group-headers=X-Remote-Group --requestheader-username-headers=X-Remote-User --secure-port=6444 --service-account-issuer=k3s --service-account-key-file=/var/lib/rancher/k3s/serve
r/tls/service.key --service-account-signing-key-file=/var/lib/rancher/k3s/server/tls/service.key --service-cluster-ip-range=10.43.0.0/16 --storage-backend=etcd3 --tls-cert-file=/var
/lib/rancher/k3s/server/tls/serving-kube-apiserver.crt --tls-private-key-file=/var/lib/rancher/k3s/server/tls/serving-kube-apiserver.key
Flag --basic-auth-file has been deprecated, Basic authentication mode is deprecated and will be removed in a future release. It is not recommended for production environments.
I0526 19:06:51.692400 1698 server.go:682] external host was not specified, using 172.27.16.180
I0526 19:06:51.692649 1698 server.go:166] Version: v1.18.2+k3s1
- 启动
kube-scheduler和kube-controller-manager
INFO[2020-05-26T19:06:57.102712037+08:00] Running kube-scheduler --bind-address=127.0.0.1 --kubeconfig=/var/lib/rancher/k3s/server/cred/scheduler.kubeconfig --leader-elect=false --p
ort=10251 --secure-port=0
INFO[2020-05-26T19:06:57.104170746+08:00] Running kube-controller-manager --allocate-node-cidrs=true --bind-address=127.0.0.1 --cluster-cidr=10.42.0.0/16 --cluster-signing-cert-file
=/var/lib/rancher/k3s/server/tls/server-ca.crt --cluster-signing-key-file=/var/lib/rancher/k3s/server/tls/server-ca.key --kubeconfig=/var/lib/rancher/k3s/server/cred/controller.kube
config --leader-elect=false --port=10252 --root-ca-file=/var/lib/rancher/k3s/server/tls/server-ca.crt --secure-port=0 --service-account-private-key-file=/var/lib/rancher/k3s/server/
tls/service.key --use-service-account-credentials=true
I0526 19:06:57.107918 1698 controllermanager.go:161] Version: v1.18.2+k3s1
I0526 19:06:57.108605 1698 deprecated_insecure_serving.go:53] Serving insecurely on [::]:10252
INFO[2020-05-26T19:06:58.129139918+08:00] Running cloud-controller-manager --allocate-node-cidrs=true --allow-untagged-cloud=true --bind-address=127.0.0.1 --cloud-provider=k3s --clu
ster-cidr=10.42.0.0/16 --kubeconfig=/var/lib/rancher/k3s/server/cred/cloud-controller.kubeconfig --leader-elect=false --node-status-update-frequency=1m --secure-port=0
Flag --allow-untagged-cloud has been deprecated, This flag is deprecated and will be removed in a future release. A cluster-id will be required on cloud instances.
I0526 19:06:58.134700 1698 controllermanager.go:120] Version: v1.18.2+k3s1
W
- 启动
kube-proxy和kubelet
INFO[2020-05-26T19:06:57.794366512+08:00] Starting k3s.cattle.io/v1, Kind=Addon controller
INFO[2020-05-26T19:06:57.794634665+08:00] Node token is available at /var/lib/rancher/k3s/server/token
INFO[2020-05-26T19:06:57.794673746+08:00] To join node to cluster: k3s agent -s https://172.27.16.180:6443 -t ${NODE_TOKEN}
INFO[2020-05-26T19:06:57.795436726+08:00] Waiting for master node startup: resource name may not be empty
I0526 19:06:57.863811 1698 controller.go:606] quota admission added evaluator for: addons.k3s.cattle.io
INFO[2020-05-26T19:06:57.903238233+08:00] Starting helm.cattle.io/v1, Kind=HelmChart controller
INFO[2020-05-26T19:06:57.903286923+08:00] Starting batch/v1, Kind=Job controller
INFO[2020-05-26T19:06:57.903313164+08:00] Starting /v1, Kind=Node controller
INFO[2020-05-26T19:06:57.903343024+08:00] Starting /v1, Kind=Service controller
INFO[2020-05-26T19:06:57.903385605+08:00] Starting /v1, Kind=Pod controller
INFO[2020-05-26T19:06:57.903411445+08:00] Starting /v1, Kind=Endpoints controller
I0526 19:06:57.921880 1698 controller.go:606] quota admission added evaluator for: deployments.apps
INFO[2020-05-26T19:06:59.097796332+08:00] Running kubelet --address=0.0.0.0 --anonymous-auth=false --authentication-token-webhook=true --authorization-mode=Webhook --cgroup-driver=c
groupfs --client-ca-file=/var/lib/rancher/k3s/agent/client-ca.crt --cloud-provider=external --cluster-dns=10.43.0.10 --cluster-domain=cluster.local --cni-bin-dir=/var/lib/rancher/k3
s/data/bd19bf78c5988a4ae051b7995298195fce498a99fd094991a90fd12a201fe63d/bin --cni-conf-dir=/var/lib/rancher/k3s/agent/etc/cni/net.d --container-runtime-endpoint=/run/k3s/containerd/
containerd.sock --container-runtime=remote --containerd=/run/k3s/containerd/containerd.sock --eviction-hard=imagefs.available<5%,nodefs.available<5% --eviction-minimum-reclaim=image
fs.available=10%,nodefs.available=10% --fail-swap-on=false --healthz-bind-address=127.0.0.1 --hostname-override=ecs-b87a --kubeconfig=/var/lib/rancher/k3s/agent/kubelet.kubeconfig -
-kubelet-cgroups=/systemd/system.slice --node-labels= --read-only-port=0 --resolv-conf=/etc/resolv.conf --runtime-cgroups=/systemd/system.slice --serialize-image-pulls=false --tls-c
ert-file=/var/lib/rancher/k3s/agent/serving-kubelet.crt --tls-private-key-file=/var/lib/rancher/k3s/agent/serving-kubelet.key
Flag --containerd has been deprecated, This is a cadvisor flag that was mistakenly registered with the Kubelet. Due to legacy concerns, it will follow the standard CLI deprecation t
imeline before being removed.
INFO[2020-05-26T19:06:59.113169378+08:00] Running kube-proxy --cluster-cidr=10.42.0.0/16 --healthz-bind-address=127.0.0.1 --hostname-override=ecs-b87a --kubeconfig=/var/lib/rancher/
k3s/agent/kubeproxy.kubeconfig --proxy-mode=iptables
W0526 19:06:59.113328 1698 server.go:225] WARNING: all flags other than --config, --write-config-to, and --cleanup are deprecated. Please begin using a config file ASAP.
INFO[2020-05-26T19:06:59.128654056+08:00] waiting for node ecs-b87a: nodes "ecs-b87a" not found
I0526 19:06:59.146328 1698 server.go:413] Version: v1.18.2+k3s1
I
- 启动网络组件flannel
I0526 19:07:12.146803 1698 vxlan.go:121] VXLAN config: VNI=1 Port=0 GBP=false Learning=false DirectRouting=false
I0526 19:07:12.193748 1698 flannel.go:78] Wrote subnet file to /run/flannel/subnet.env
I0526 19:07:12.193768 1698 flannel.go:82] Running backend.
I0526 19:07:12.193774 1698 vxlan_network.go:60] watching for new subnet leases
I0526 19:07:12.201828 1698 iptables.go:145] Some iptables rules are missing; deleting and recreating rules
I0526 19:07:12.201875 1698 iptables.go:167] Deleting iptables rule: -s 10.42.0.0/16 -d 10.42.0.0/16 -j RETURN
I0526 19:07:12.202960 1698 iptables.go:145] Some iptables rules are missing; deleting and recreating rules
I0526 19:07:12.202999 1698 iptables.go:167] Deleting iptables rule: -s 10.42.0.0/16 -j ACCEPT
I0526 19:07:12.204866 1698 iptables.go:167] Deleting iptables rule: -s 10.42.0.0/16 ! -d 224.0.0.0/4 -j MASQUERADE --random-fully
I0526 19:07:12.205931 1698 iptables.go:167] Deleting iptables rule: -d 10.42.0.0/16 -j ACCEPT
I0526 19:07:12.207820 1698 iptables.go:167] Deleting iptables rule: ! -s 10.42.0.0/16 -d 10.42.0.0/24 -j RETURN
I0526 19:07:12.209118 1698 iptables.go:155] Adding iptables rule: -s 10.42.0.0/16 -j ACCEPT
I0526 19:07:12.210083 1698 iptables.go:167] Deleting iptables rule: ! -s 10.42.0.0/16 -d 10.42.0.0/16 -j MASQUERADE --random-fully
I0526 19:07:12.211653 1698 iptables.go:155] Adding iptables rule: -s 10.42.0.0/16 -d 10.42.0.0/16 -j RETURN
I0526 19:07:12.214128 1698 iptables.go:155] Adding iptables rule: -d 10.42.0.0/16 -j ACCEPT
I0526 19:07:12.217520 1698 iptables.go:155] Adding iptables rule: -s 10.42.0.0/16 ! -d 224.0.0.0/4 -j MASQUERADE --random-fully
I0526 19:07:12.225410 1698 iptables.go:155] Adding iptables rule: ! -s 10.42.0.0/16 -d 10.42.0.0/24 -j RETURN
I0526 19:07:12.228914 1698 iptables.go:155] Adding iptables rule: ! -s 10.42.0.0/16 -d 10.42.0.0/16 -j MASQUERADE --random-fully
部署一个演示程序
alias k='$(pwd)/k3s-arm64 kubectl'
k run hello-arm --image=registry.cn-hangzhou.aliyuncs.com/k8ops/hello:0.1
k get pod
k logs -f hello-arm
输出下面日志确定OK
NAME READY STATUS RESTARTS AGE
hello-arm 0/1 Completed 0 2s
Hello, my architecture is Linux buildkitsandbox 4.19.76-linuxkit #1 SMP Thu Oct 17 19:31:58 UTC 2019 aarch64 Linux
如何实现容器镜像多平台包构建 ?
呼之欲出buildx
啥子是buildx ? 自己bing, 文档地址:docker/buildx
安装
- buildx安装
# 从 https://github.com/docker/buildx/releases 下载 对应平台的buildx,比如: buildx-v0.4.1.darwin-amd64
mkdir -p $HOME/.docker/cli-plugins/
mv buildx-v0.4.1.darwin-amd64 $HOME/.docker/cli-plugins/docker-buildx
export DOCKER_CLI_EXPERIMENTAL=enabled
docker buildx version
输出下面日志是OK
github.com/docker/buildx v0.4.1 bda4882a65349ca359216b135896bddc1d92461c
- 创建builder的时候需要的镜像装备
docker pull registry.cn-hangzhou.aliyuncs.com/k8ops/moby-buildkit:buildx-stable-1
docker tag registry.cn-hangzhou.aliyuncs.com/k8ops/moby-buildkit:buildx-stable-1 moby/buildkit:buildx-stable-1
docker images |grep moby
输出效果如下:
moby/buildkit buildx-stable-1 f2a88cb62c92 5 weeks ago 82.8MB
registry.cn-hangzhou.aliyuncs.com/k8ops/moby-buildkit buildx-stable-1 f2a88cb62c92 5 weeks ago 82.8MB
- 创建builder
docker buildx create --name mybuilder
docker buildx use mybuilder
docker buildx inspect --bootstrap
[+] Building 12.0s (1/1) FINISHED
=> [internal] booting buildkit 11.9s
=> => pulling image moby/buildkit:buildx-stable-1 10.9s
=> => creating container buildx_buildkit_mybuilder0 1.1s
Name: mybuilder
Driver: docker-container
Nodes:
Name: mybuilder0
Endpoint: unix:///var/run/docker.sock
Status: running
Platforms: linux/amd64, linux/arm64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
创建hello镜像
file: hello.c
/*
* hello.c
*/
#include <stdio.h>
#include <stdlib.h>
#ifndef ARCH
#define ARCH "Undefined"
#endif
int main() {
printf("Hello, my architecture is %s\n", ARCH);
exit(0);
}
file: Dockerfile
#
# Dockerfile
#
FROM alpine AS builder
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories \
&& apk update
RUN apk add build-base
WORKDIR /home
COPY hello.c .
RUN gcc "-DARCH=\"`uname -a`\"" hello.c -o hello
FROM alpine
WORKDIR /home
COPY --from=builder /home/hello .
ENTRYPOINT ["./hello"]
mkdir huawei-arm-k3s
touch hello.c Dockerfile
docker buildx build --platform linux/arm,linux/arm64,linux/amd64 -t registry.cn-hangzhou.aliyuncs.com/k8ops/hello:0.1 . --push
docker buildx imagetools inspect registry.cn-hangzhou.aliyuncs.com/k8ops/hello:0.1
Name: registry.cn-hangzhou.aliyuncs.com/k8ops/hello:0.1
MediaType: application/vnd.docker.distribution.manifest.list.v2+json
Digest: sha256:6c7714c17223d788c0bf26f9f45e1af9c5edd3478c990c4051a72d8e9cd5aa5c
Manifests:
Name: registry.cn-hangzhou.aliyuncs.com/k8ops/hello:0.1@sha256:9eb62f00457b9eff252fc6143dfd33d80d31a5013cf08a8ab0132394262198e7
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/arm64
Name: registry.cn-hangzhou.aliyuncs.com/k8ops/hello:0.1@sha256:d7244652b1ce9b0bd1060be8a861a5aff2d5a893cd0ba3afb0db68a225034893
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/amd64
本地验证
docker run --rm -it registry.cn-hangzhou.aliyuncs.com/k8ops/hello:0.1@sha256:d7244652b1ce9b0bd1060be8a861a5aff2d5a893cd0ba3afb0db68a225034893
Unable to find image 'registry.cn-hangzhou.aliyuncs.com/k8ops/hello:0.1@sha256:d7244652b1ce9b0bd1060be8a861a5aff2d5a893cd0ba3afb0db68a225034893' locally
sha256:d7244652b1ce9b0bd1060be8a861a5aff2d5a893cd0ba3afb0db68a225034893: Pulling from k8ops/hello
cbdbe7a5bc2a: Already exists
e26bd31f84ac: Already exists
b72c012d327f: Pull complete
Digest: sha256:d7244652b1ce9b0bd1060be8a861a5aff2d5a893cd0ba3afb0db68a225034893
Status: Downloaded newer image for registry.cn-hangzhou.aliyuncs.com/k8ops/hello@sha256:d7244652b1ce9b0bd1060be8a861a5aff2d5a893cd0ba3afb0db68a225034893
Hello, my architecture is Linux buildkitsandbox 4.19.76-linuxkit #1 SMP Thu Oct 17 19:31:58 UTC 2019 x86_64 Linux
如何在ARM上运行k3s? 窥探k3s启动过程!,内附容器多平台包构建的更多相关文章
- 如何在yarn上运行Hello World(二)
在之前的一篇文章我们介绍了如何编写在yarn集群提交运行应用的AM的yarnClient端,现在我们来继续介绍如何编写在yarn集群控制应用app运行的核心模块 ApplicationMaster ...
- C#语言支持的特性,.NET却不支持,那么C#不被.NET支持的部分又是如何在.NET上运行的呢?
阅读<C#高级编程>系列丛书中,介绍C#与.NET的关系,提到C#是语言,.NET是平台(C#不是.NET的一部分),说".NET支持的一些特性,C#并不支持",这个可 ...
- 如何在yarn上运行Hello World(一)
1.YARN是什么 YARN (Yet Another Resource Negotiator,另一种资源协调者) 是hadoop上的一种资源调度器,它是一个通用资源管理系统,可以为上层应用提供统一 ...
- vs2012+ winform+.net4.0发布如何在xp上运行
今天在英文版vs2013打包发布4.0(非4.0 client)的winform时,遇到了在xp上无法运行的情况,.net framework 4.0在xp上已安装.在打包前,winform工程,即菜 ...
- FineReport做成之后如何在Tomcat上运行
问题描述: 自己用FineReport做成的报表画面,要在Tomcat上运行启动 第一步:下载Tomcat 网址: http://tomcat.apache.org/download-80.cgi 下 ...
- ios那些事之如何在ios5上运行gdb
为啥要在ios上运行gdb? 这个问题见仁见智喽.对于搞开发的同学们来所, 有了gdb更方便跟踪分析别人的程序,取长补短:)这里不是教大家crack:) 运行环境: Mac OS 10.7.4 Xco ...
- 如何在MAC上运行exe程序
1. 首先下载并运行CrossOver 运行CrossOver需要收费,试用期为14天,运行CrossOver 2. 选择exe应用程序,新建容器,安装exe程序 3.安装成功后,运行exe应用程序启 ...
- 如何在mac上运行vue项目
使用终端安装Vue运行环境 1.安装 Homebrew Homebrew 是osx下面最优秀的包管理工具,没有之一.先在终端查看是否已安装brew brew -v 如果返回 Homebrew 的版本号 ...
- 如何在submit上运行php文件
一..把php加入到环境变量 二.在sublmie中新建编译系统 三.添加一下代码,修改成php当前的目录地址,保存在默认的路径下,命名为php.sublime-build { "cmd&q ...
随机推荐
- DP背包(一)
01背包 for(int i=0;i<n;i++) //遍历每一件物品 for(int j=v;j>=wei[i];j--)//遍历背包容量,表示在上一层的基础上,容量为J时,第i件物品装 ...
- andorid jar/库源码解析之retrofit2
目录:andorid jar/库源码解析 Retrofit2: 作用: 通过封装okhttp库,来进行web通讯,并且使用动态代理的方式,来调用接口地址,通过回调赋值结果. 栗子: 定义一个接口,用于 ...
- shell bash终端中输出的颜色和格式详解(超详细)
文章目录 1) 格式 1.1 Set 1.2 Reset 2)8/16 Colors 2.1 前景(文字) 2.2 背景 3)88/256颜色 3.1 前景(文字) 3.2 背景色 4)组合属性 5) ...
- Hexo 博客利用 Nginx 实现中英文切换
本文记录了对 Hexo 博客进行中英文切换的配置过程,实现同一应用共用模版,任何页面可以切换到另一语言的对应页面,并对未明确语言的访问地址,根据浏览器语言进行自动跳转 实现细则 中英文地址区分 博客中 ...
- CF-292D Connected Components 并查集 好题
D. Connected Components 题意 现在有n个点,m条编号为1-m的无向边,给出k个询问,每个询问给出区间[l,r],让输出删除标号为l-r的边后还有几个连通块? 思路 去除编号为[ ...
- 简述异步编程&Promise&异步函数
前言:文章由本人在学习之余总结巩固思路,不足之前还请指出. 一.异步编程 首先我们先简单来回顾一下同步API和异步API的概念 1.同步API:只有当前的API执行完成之前,才会执行下一个API 例: ...
- 学习python的第一天,python的简单知识
python 是现如今比较火的一种编程语言.在抱着试试的态度我来进行学习下python.要学习python 要先进行环境的安装. 下面是下载链接:https://pan.baidu.com/s/1PW ...
- mysql批量导入删除
批量导入 <insert id="extractOrderBaseHis">INSERT INTO `odr_order_base_his`(`order_base_i ...
- 【漫画】CAS原理分析!无锁原子类也能解决并发问题!
本文来源于微信公众号[胖滚猪学编程].转载请注明出处 在漫画并发编程系统博文中,我们讲了N篇关于锁的知识,确实,锁是解决并发问题的万能钥匙,可是并发问题只有锁能解决吗?今天要出场一个大BOSS:CAS ...
- APP测试知识中的monkey测试
了解了logging模块的应用 1)两种方式,1:日志级别函数 2:日志级别的四大组件来实现日志功能(日志流处理) 2)日志流处理日志logging四大组件:logger(日志器) ...