Docker概述
Docker文檔中心: https://docs.docker.com/
Docker商店: https://hub.docker.com/
Docker為什么出現(xiàn)勤揩?
一款產(chǎn)品:開發(fā)-上線 兩套環(huán)境,各不相同,維護(hù)麻煩溶诞!
開發(fā)--運(yùn)維 開發(fā)在自己的電腦上運(yùn)行良好,然后把項(xiàng)目打成jar包或是war包拧篮,丟給運(yùn)維词渤,運(yùn)維需要配置各種環(huán)境,各種集群串绩,壓力超大缺虐,而且還很有可能失敗礁凡!
版本更新高氮,導(dǎo)致服務(wù)不可用!
Docker可以把項(xiàng)目和它所依賴的環(huán)境整合打包顷牌,非常方便剪芍!
Docker的思想就來自于集裝箱,應(yīng)用之間相互隔離窟蓝,隔離的思想
Docker通過隔離機(jī)制罪裹,將服務(wù)器利用到極致
Docker安裝步驟
?#1、卸載舊的版本
?$ sudo yum remove docker \
? ? ? ? ? ? ? ? ? ?docker-client \
? ? ? ? ? ? ? ? ? ?docker-client-latest \
? ? ? ? ? ? ? ? ? ?docker-common \
? ? ? ? ? ? ? ? ? ?docker-latest \
? ? ? ? ? ? ? ? ? ?docker-latest-logrotate \
? ? ? ? ? ? ? ? ? ?docker-logrotate \
? ? ? ? ? ? ? ? ? ?docker-engine
?#2运挫、需要安裝包
?yum install -y yum-utils
?#3状共、設(shè)置鏡像地址
?官方地址:
?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軟件包索引
?yum makecache fast
?
?#4、安裝docker相關(guān)的
?yum install docker-ce docker-ce-cli containerd.io
?#5谁帕、啟動docker
? ? ?systemctl start docker
?#6峡继、判斷Docker是否啟動成功
?docker version
?#7、測試DOcker
?docker run hello-world
?#8雇卷、查看鏡像
?docker images
?#9鬓椭、配置 阿里云docker 鏡像加速(要配置你自己的)
?sudo mkdir -p /etc/docker
?
?sudo tee /etc/docker/daemon.json <<-'EOF'
?{
? ?"registry-mirrors": ["https://5mybeny2.mirror.aliyuncs.com"]
?}
?EOF
?
?sudo systemctl daemon-reload
?
?sudo systemctl restart docker
登錄你自己的阿里云賬號颠猴,找到自己的鏡像加速如下圖:
卸載
?#1关划、卸載Docker Engine,CLI和Containerd軟件包:
?$ sudo yum remove docker-ce docker-ce-cli containerd.io
?#2翘瓮、主機(jī)上的映像贮折,容器,卷或自定義配置文件不會自動刪除资盅。要刪除所有圖像调榄,容器和卷:
?$ sudo rm -rf /var/lib/docker
Docker流程
Docker組成
Docker運(yùn)行流程圖
Docker底層原理
Docker是怎么工作的
Docker是server-client結(jié)構(gòu)的系統(tǒng),Docker的守護(hù)進(jìn)程運(yùn)行在主機(jī)上呵扛,通過socket從客戶端訪問
Docker-server接收到Docker-client的指令每庆,就會去執(zhí)行這個(gè)指令
Docker為什么比虛擬機(jī)快
1.Docker有著比虛擬機(jī)更少的抽象層,由于Docker不需要Hypervisor實(shí)現(xiàn)硬件資源虛擬化今穿,運(yùn)行在Docker容器上的程序直接使用的都是實(shí)際物理機(jī)的硬件資源缤灵,因此在Cpu、內(nèi)存利用率上Docker將會在效率上有明顯優(yōu)勢。
2.Docker利用的是宿主機(jī)的內(nèi)核腮出,而不需要Guest OS帖鸦,因此,當(dāng)新建一個(gè)容器時(shí)胚嘲,Docker不需要和虛擬機(jī)一樣重新加載一個(gè)操作系統(tǒng)作儿,避免了引導(dǎo)、加載操作系統(tǒng)內(nèi)核這個(gè)比較費(fèi)時(shí)費(fèi)資源的過程馋劈,當(dāng)新建一個(gè)虛擬機(jī)時(shí)攻锰,虛擬機(jī)軟件需要加載Guest OS,這個(gè)新建過程是分鐘級別的侣滩,而Docker由于直接利用宿主機(jī)的操作系統(tǒng)則省略了這個(gè)過程口注,因此新建一個(gè)Docker容器只需要幾秒鐘。
Docker的常用命令
幫助命令
?docker version #查看docker版本信息
?docker info ?? #查看docker系統(tǒng)信息
?docker --help ?#查看docker幫助命令
鏡像命令
查詢本地已有鏡像:
?docker?images?-qa?#一般用這個(gè)君珠,其中q表示顯示id寝志,a顯示所有
查詢商店中相關(guān)軟件: docker search
?docker?search?mysql
下載鏡像
?docker?pull?鏡像名[:tag]
刪除鏡像
?docker rmi -f 鏡像id1 鏡像id2 #刪除多個(gè)鏡像
?docker rmi -f $(docker images -qa) #刪除全部鏡像
容器命令
ps:我們有了鏡像才能創(chuàng)建容器,下載一個(gè)centos鏡像來學(xué)習(xí)
?docker?pull?centos
新建容器并啟動
?docker run [可選參數(shù)] image
?#參數(shù)說明
?--name="Name" 容器名字
?-d ?以后臺方式運(yùn)行
?-it 使用交互方式運(yùn)行策添,進(jìn)入容器查看
?-p(小p) 指定容器的端口
? -p 主機(jī)端口:容器端口
? -p 容器端口
?-P(大p) 隨機(jī)指定端口
?例子:docker run -it centos /bin/bash
列出所有正在運(yùn)行的容器
?docker ps
? 沒有參數(shù)查看正在運(yùn)行的容器
?-a ?查看曾經(jīng)運(yùn)行過的
?-n=? 顯示最近創(chuàng)建的容器
?-q ?只顯示容器的編號
退出容器
?exit 直接容器停止并退出
?ctrl+p+q ?容器不停止退出
刪除容器
?docker rm 容器id ?刪除指定的容器材部,容器正在運(yùn)行則不能刪除
?docker rm -f $(docker ps -aq) 刪除所有容器
?docker ps -a -q|xargs docker rm 刪除所有容器
啟動和停止容器的操作
?docker start 容器id ?#啟動容器
?docker restart 容器id #重啟容器
?docker stop 容器id #停掉容器
?docker kill 容器id #殺掉容器
其他命令
后臺啟動容器
?docker run -d 鏡像名
?#docker ps,發(fā)現(xiàn)centos停止了
?#常見的坑唯竹,docker容器使用后臺啟動乐导,就必須有一個(gè)前臺進(jìn)程,docker發(fā)現(xiàn)沒有應(yīng)用浸颓,就會自動停止
?#解決辦法物臂,以這個(gè)命令啟動:docker run -d -it centos /bin/bash
查看日志
?docker logs -tf --tail 10 容器id
?-tf 顯示全部的
?--tail number 顯示指定條數(shù)
查看容器中進(jìn)程信息
?docker?top?容器id
查看鏡像元數(shù)據(jù)
?docker?inspect?容器id
進(jìn)入當(dāng)前正在運(yùn)行的容器
?#方式一,進(jìn)入容器開啟一個(gè)新終端
?docker exec -it 容器id /bin/bash
?#方式二产上,進(jìn)入容器正在執(zhí)行的終端
?docker attach 容器id
從容器內(nèi)拷貝文件到主機(jī)上
?docker?cp?容器id:容器內(nèi)路徑??目的主機(jī)路徑
Docker操作詳細(xì)圖解
作業(yè)練習(xí)
Docker安裝nginx
?#1棵磷、搜索鏡像
?docker search nginx
?#2、拉取鏡像
?docker pull nginx
?#3晋涣、啟動容器
?docker run -d --name nginx01 -p 3304:80 nginx
?ps:3304是主機(jī)端口仪媒,暴露給外部訪問,80是容器內(nèi)部的端口
端口暴露的概念:
思考問題:我們每次改動nginx配置文件谢鹊,都要進(jìn)入容器內(nèi)部算吩?十分的麻煩,我們可以在容器外提供一個(gè)映射路徑佃扼,達(dá)到在容器外修改偎巢,容器內(nèi)就能修改? -v ?數(shù)據(jù)卷
Docker安裝tomcat
?#官方使用
?docker run -it --rm tomcat:9.0
?--rm:用完之后立即刪掉
?#docker啟動的tomcat發(fā)現(xiàn)以下問題:1兼耀、Linux命令少了压昼;2挎扰、沒有webapps 3、阿里云鏡像默認(rèn)是最小得鏡像巢音,所有不必要的都剔除掉遵倦,保證最小的可運(yùn)行環(huán)境
部署es+kibana
?#es暴露的端口很多,十分耗內(nèi)存
?#數(shù)據(jù)一般要放到安全目錄官撼,掛載
?#1梧躺、拉取鏡像
?docker pull elasticsearch:7.14.2
?#2、創(chuàng)建用戶自定義網(wǎng)絡(luò)
?docker network create hahanetwork
?#3傲绣、運(yùn)行es:
?docker run --name elasticsearch --net hahanetwork -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" -d elasticsearch:7.14.2
?#ps:這個(gè)啟動之后超級卡掠哥,linux終端都卡住了
?#docker stats 查看狀態(tài)
思考:kibana連接es?思考網(wǎng)絡(luò)如何才能連接過去秃诵!
Docker鏡像
鏡像是什么
鏡像是一層一層的续搀,我們從商店中pull一個(gè)應(yīng)用到本地,它是一層一層下載的菠净,鏡像就是這種有很多層疊加而來的
鏡像不但包含了軟件包本身禁舷,還包含了其所需運(yùn)行環(huán)境,各種配置毅往,所以鏡像只需要啟動就可以使用了牵咙,免去了以前安裝軟件時(shí),各種安裝依賴攀唯、修改配置等繁瑣的工作
Docker鏡像加載原理
加載boot層洁桌,也就是引導(dǎo)層
加載root層,也就是/root 侯嘀,/user這些linux目錄
加載容器層另凌,也就是docker本身相關(guān)的東西
?#1、docker加載的底層層級能共用的就共用戒幔,比如tomcat和mysql共用了boot層
?#2吠谢、docker之所以快,一是因?yàn)樗拿恳粚佣急M量精簡溪食,也就是閹割版囊卜;二是因?yàn)樗恍枰看味既ゼ虞dboot層娜扇,boot層加載時(shí)間是分鐘級別的错沃,容器層加載時(shí)秒級別的
Docker鏡像都是只讀的,當(dāng)容器啟動時(shí)雀瓢,一個(gè)新的可寫層被加入到鏡像的頂部枢析!
這一層就是我們通常所說的容器層,容器層之下都是鏡像層刃麸!
commit鏡像
commit鏡像的意思是說把一個(gè)容器生成為一個(gè)本地鏡像醒叁,并沒有上傳到docker商店
?#命令和git原理類似
?docker commit -m="提交的描述信息" -a="作者" 容器id 目標(biāo)鏡像名:[TAG]
?#commit鏡像類似于虛擬機(jī)的快照
容器數(shù)據(jù)卷
什么是容器數(shù)據(jù)卷
docker理念回顧
將應(yīng)用和環(huán)境打包成一個(gè)鏡像!
數(shù)據(jù)?如果數(shù)據(jù)在容器中把沼,那么我們刪除容器啊易,數(shù)據(jù)就會丟失!需求:數(shù)據(jù)可以持久化
mysql饮睬,容器刪了租谈,刪庫跑路!需求:mysql數(shù)據(jù)可以本地存儲
容器之間可以有一個(gè)數(shù)據(jù)共享的技術(shù)捆愁!Docker容器產(chǎn)生的數(shù)據(jù)割去,同步到本地!
這就是卷技術(shù)昼丑!目錄的掛載呻逆,將我們?nèi)萜鲀?nèi)的目錄,掛載到linux上面菩帝!
總結(jié):容器的持久化和同步操作,容器間的數(shù)據(jù)也是可以共享的?С恰(可以和vue的雙向綁定類比)
以后我們只需要修改本地即可,容器內(nèi)會自動同步
使用數(shù)據(jù)卷
方式一:直接使用命令掛載 -v
?docker?run?-it?-v?本機(jī)目錄:容器目錄??鏡像id?/bin/bash
實(shí)戰(zhàn):同步mysql數(shù)據(jù)
?#1呼奢、下載mysql
?[root@localhost dockerfile]# docker pull mysql:5.7
?
?#2酒繁、啟動mysql容器
?-d 后臺運(yùn)行
?-p 端口映射
?-v 卷掛載
?-e 環(huán)境配置
?--name 指定容器名字
?[root@localhost dockerfile]# docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=admin --name mysql01 mysql:5.7
?
?#3、在本地用navicat連接mysql控妻,新建一個(gè)數(shù)據(jù)庫test州袒,可以在linux中和mysql容器中查看到test
?[root@localhost dockerfile]# cd /home/mysql/data/
?[root@localhost data]# ls
?auto.cnf ? ?client-cert.pem ?ibdata1 ? ? ?ibtmp1 ? ? ? ? ? ? ?private_key.pem ?server-key.pem
?ca-key.pem ?client-key.pem ? ib_logfile0 ?mysql ? ? ? ? ? ? ? public_key.pem ? sys
?ca.pem ? ? ?ib_buffer_pool ? ib_logfile1 ?performance_schema ?server-cert.pem ?test
?[root@localhost data]# docker exec -it b9ff5c7b7ce7 /bin/bash
?root@b9ff5c7b7ce7:/# cd /var/lib/mysql
?root@b9ff5c7b7ce7:/var/lib/mysql# ls
?auto.cnf ? ?client-cert.pem ?ib_logfile0 ?ibtmp1 ? ? ? ? ? ? ?private_key.pem ?server-key.pem
?ca-key.pem ?client-key.pem ? ib_logfile1 ?mysql ? ? ? ? ? ? ? public_key.pem ? sys
?ca.pem ? ? ?ib_buffer_pool ? ibdata1 ? ? ?performance_schema ?server-cert.pem ?test
具名掛載和匿名掛載
?docker run -d -P --name nginx01 -v [卷名:]/etc/nginx[:ro|rw] nginx
?#解釋:只寫容器內(nèi)路徑,不指定本地路徑弓候,是匿名掛載郎哭,寫了卷名是具名掛載,
?#ro表示在容器內(nèi)部只讀,但在外面可以修改
?#rw表示可讀可寫
?#配置文件建議rw菇存,數(shù)據(jù)庫文件建議ro
?docker volume ls
?docker volume inspect 卷名
所有的docker容器內(nèi)的卷夸研,沒有指定目錄的情況下都是在/var/lib/docker/volume/xxx/_data
我們可以通過具名掛載方便地找到我們的一個(gè)卷,大多數(shù)情況下使用具名掛載
?#如何確定是具名掛載還是匿名掛載依鸥,還是指定路徑掛載
?-v 容器內(nèi)路徑 ?#匿名掛載
?-v 卷名:容器內(nèi)路徑 ?#具名掛載
?-v /宿主機(jī)路徑:容器內(nèi)路徑 #指定路徑掛載
方式二:使用Dockerfile
Dockerfile就是用來構(gòu)建docker鏡像的構(gòu)建文件亥至,是一段命令腳本
實(shí)驗(yàn):編寫一個(gè)Dockerfile
生成鏡像命令:
?docker build -f /home/docker/dockerfile01 -t 鏡像名 .
?#ps:最后有一個(gè)"."
數(shù)據(jù)卷容器
多個(gè)mysql同步數(shù)據(jù)!
--volumes-from
案例:多個(gè)mysql實(shí)現(xiàn)數(shù)據(jù)共享
?[root@localhost dockerfile]# docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=admin --name mysql01 mysql:5.7
?
?[root@localhost dockerfile]# docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=admin --name mysql02 mysql:5.7 --volumes-from mysql01
結(jié)論:
容器之間配置信息的傳遞贱迟,數(shù)據(jù)卷容器的生命周期一直持續(xù)到?jīng)]有容器使用為止
DockerFile
Dokerfile是用來構(gòu)建docker鏡像的文件姐扮!命令參數(shù)腳本!
構(gòu)建步驟:
編寫一個(gè)dockerfile文件
docker ?build構(gòu)建一個(gè)鏡像
docker run運(yùn)行鏡像
docker push發(fā)布鏡像(DockerHub衣吠、阿里云鏡像倉庫)
Dockerfile構(gòu)建過程
基礎(chǔ)知識:
每個(gè)保留關(guān)鍵字(指令)都必須是大寫字母
執(zhí)行從上到下執(zhí)行
#表示注釋
每一個(gè)指令都會創(chuàng)建提交一個(gè)新的鏡像層
dockerfile是面向開發(fā)的茶敏,我們以后要發(fā)布項(xiàng)目,做鏡像缚俏,就要編寫dockerfile文件惊搏,發(fā)布項(xiàng)目鏡像給下游贮乳!
Docker鏡像逐漸成為企業(yè)交付的標(biāo)準(zhǔn),必須要掌握恬惯!
步驟:開發(fā)向拆、部署、運(yùn)維酪耳。亲铡。。缺一不可葡兑!
Dockerfile:構(gòu)建文件奖蔓,定義了一切的步驟,源代碼
DockerImage:通過Dockerfile構(gòu)建生成的鏡像讹堤,最終發(fā)布和運(yùn)行的產(chǎn)品(以前是jar和war包)
Docker容器:容器就是鏡像運(yùn)行起來提供服務(wù)
Dockerfile構(gòu)建指令:
實(shí)戰(zhàn)測試
實(shí)戰(zhàn)1:創(chuàng)建自己的centos:
1吆鹤、原始的centos沒有vim和ifconfig
?
?[root@localhost dockerfile]# docker images
?REPOSITORY ? ? ?TAG ? ? ? IMAGE ID ? ? ? CREATED ? ? ? SIZE
?hello-world ? ? latest ? ?feb5d9fea6a5 ? 3 weeks ago ? 13.3kB
?centos ? ? ? ? ?latest ? ?5d0da3dc9764 ? 4 weeks ago ? 231MB
?elasticsearch ? 7.14.2 ? ?2abd5342ace0 ? 4 weeks ago ? 1.04GB
?[root@localhost dockerfile]# docker run -it centos
?[root@7a61c7e92b9f /]# pwd
?/
?[root@7a61c7e92b9f /]# vim
?bash: vim: command not found
?[root@7a61c7e92b9f /]# ifconfig
?bash: ifconfig: command not found
?[root@7a61c7e92b9f /]# ifconfig
?bash: ifconfig: command not found
2、構(gòu)建dockerfile文件
?[root@localhost dockerfile]# vi mydockerfile.centos
?[root@localhost dockerfile]# cat mydockerfile.centos
?FROM centos
?MAINTAINER whw<353538982@qq.com>
?
?ENV MYPATH /usr/local
?WORKDIR $MYPATH
?
?RUN yum -y install vim
?RUN yum -y install net-tools
?
?EXPOSE 80
?
?ENTRYPOINT echo $MYPATH
?ENTRYPOINT echo "---END---"
?ENTRYPOINT /bin/bash
3洲守、構(gòu)建鏡像
?[root@localhost?dockerfile]#?docker?build?-f?mydockerfile.centos?-t?mycentos:0.1?.
4疑务、運(yùn)行容器并驗(yàn)證
?[root@localhost dockerfile]# docker images
?REPOSITORY ? ? ?TAG ? ? ? IMAGE ID ? ? ? CREATED ? ? ? ? ?SIZE
?mycentos ? ? ? ?0.1 ? ? ? 93cdc922f14e ? 43 seconds ago ? 336MB
?hello-world ? ? latest ? ?feb5d9fea6a5 ? 3 weeks ago ? ? ?13.3kB
?centos ? ? ? ? ?latest ? ?5d0da3dc9764 ? 4 weeks ago ? ? ?231MB
?elasticsearch ? 7.14.2 ? ?2abd5342ace0 ? 4 weeks ago ? ? ?1.04GB
?[root@localhost dockerfile]# docker run -it mycentos:0.1 /bin/bash
?[root@c8f0ff352c8a local]# pwd
?/usr/local
?[root@c8f0ff352c8a local]# ifconfig
?eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> ?mtu 1500
? ? ? ? ?inet 172.17.0.2 ?netmask 255.255.0.0 ?broadcast 172.17.255.255
? ? ? ? ?ether 02:42:ac:11:00:02 ?txqueuelen 0 ?(Ethernet)
? ? ? ? ?RX packets 8 ?bytes 656 (656.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
?
?lo: flags=73<UP,LOOPBACK,RUNNING> ?mtu 65536
? ? ? ? ?inet 127.0.0.1 ?netmask 255.0.0.0
? ? ? ? ?loop ?txqueuelen 1000 ?(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
?
實(shí)戰(zhàn)2:創(chuàng)建自己的tomcat鏡像
1、準(zhǔn)備鏡像文件tomcat壓縮包梗醇、jdk壓縮包
?[root@localhost dockerfile]# ll
?total 153428
?-rw-r--r--. 1 root root ?11576317 Oct 17 01:52 apache-tomcat-9.0.54.tar.gz
?-rw-r--r--. 1 root root 145520298 Oct 17 01:52 jdk-8u301-linux-x64.tar.gz
?-rw-r--r--. 1 root root ? ? ? 201 Oct 16 15:02 mydockerfile.centos
?-rw-r--r--. 1 root root ? ? ? 550 Oct 17 02:10 mydockerfile.tomcat
?
2知允、編寫Dockerfile文件
?[root@localhost dockerfile]# cat mydockerfile.tomcat
?#基礎(chǔ)鏡像
?FROM centos
?
?#作者
?MAINTAINER whw<353538982@qq.com>
?
?#設(shè)置工作目錄
?ENV MYPATH /usr/local
?WORKDIR $MYPATH
?
?#復(fù)制文件
?COPY readme.txt $MYPATH/readme.txt
?
?#添加jdk和tomcat到容器
?ADD apache-tomcat-9.0.54.tar.gz $MYPATH
?ADD jdk-8u301-linux-x64.tar.gz $MYPATH
?
?#安裝vim
?RUN yum -y install vim
?
?#設(shè)置環(huán)境變量
?
?ENV JAVA_HOME $MYPATH/jdk1.8.0_301
?ENV PATH $PATH:$JAVA_HOME/bin
?
?#暴露端口
?EXPOSE 8080
?
?#啟動tomcat(注意:這里CMD建議用ENTRYPOINT代替,否則啟動容器時(shí)如果后面加了命令如/bin/bash很可能不會啟動tomcat)
?CMD ["/usr/local/apache-tomcat-9.0.54/bin/catalina.sh","run"]
3叙谨、構(gòu)建鏡像
?[root@localhost?dockerfile]#?docker?build?-f?mydockerfile.tomcat?-t?mytomcat:1.0?.
4温鸽、運(yùn)行鏡像并驗(yàn)證
?docker?run?-it?-p?9090:8080?--name?diytomcat?mytomcat:1.0
原創(chuàng)不易,拒絕白嫖手负,請點(diǎn)贊和關(guān)注涤垫,微信公眾號:java時(shí)光