Alpine使用的不是正統(tǒng)的glibc,對(duì)于一些強(qiáng)依賴glibc的系統(tǒng)建議不要使用Alpine,比如使用了Oracle JDK的系統(tǒng),建議在Alpine換成OpenJDK。
Alpine官方給出了Alpine的三大特征 Small、Simple、Secure,但其實(shí)我們知道一個(gè)jdk就已經(jīng)不小了,強(qiáng)行安裝只會(huì)違背Alpine的設(shè)計(jì)初衷,最后其實(shí)與其他操作系統(tǒng)差不多了。所以對(duì)于JAVA程序來說使用centos等操作系統(tǒng)會(huì)更好一下。
那么強(qiáng)行安裝Oracle JDK會(huì)怎樣呢,下面我們來討論一下
常規(guī)流程安裝JDK
下載一個(gè)Oracle JDK,隨便哪個(gè)版本都行吧,一般來說java程序員JDK還是有的,就不帶大家安裝了,提前準(zhǔn)備了一個(gè),將JDK拷貝到Alpine容器
Docker cp jdk1.8.0_231.tar.gz alpine:/usr/local/share/java
Alpine容器里解壓查看jdk版本
/usr/local/share/java # ls
jdk1.8.0_231.tar.gz
## 解壓
tar -zxvf jdk1.8.0_231.tar.gz
## 重新命個(gè)名
mv jdk1.8.0_231 jdk
## 查看版本 not found問題
/usr/local/share/java # /usr/local/share/java/jdk/bin/java -version
/bin/sh: /usr/local/share/java/jdk/bin/java: not found
又是似曾相識(shí)的問題,上篇文章講到了,創(chuàng)建一個(gè)軟連接就行
Alpine執(zhí)行其他操作系統(tǒng)的二進(jìn)制文件報(bào)錯(cuò)not found問題
mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2
## 再次執(zhí)行還是報(bào)錯(cuò)了 這次是缺少動(dòng)態(tài)鏈接庫(kù)
/usr/local/share/java # /usr/local/share/java/jdk/bin/java -version
Error relocating /usr/local/share/java/jdk/bin/../lib/amd64/jli/libjli.so: __strdup: symbol not found
Error relocating /usr/local/share/java/jdk/bin/../lib/amd64/jli/libjli.so: __rawmemchr: symbol not found
缺少動(dòng)態(tài)鏈接庫(kù),這些庫(kù)我也不認(rèn)識(shí)呀,這么大問題,總有人給alpine反饋吧。下面我就來看看大佬們?cè)趺纯创伞?/p>
大佬們的爭(zhēng)議
貌似看到了一個(gè)官方解答
This is more of a musl libc issue.
The Oracle Java binaries only run on glibc at the moment.
We are looking at possibly rebuilding https://aur.archlinux.org/packages/jd/jdk/PKGBUILD
and making it avAIlable as a standalone package.
I'll keep this issue open for now as we have had requests for Java 8 multiple times already.
## 這是musl libc的一個(gè)問題,Oracle JDK的二進(jìn)制文件只能在glibc下運(yùn)行,我們正在考慮重新編譯jdk的包使其作為alpine中一個(gè)獨(dú)立的包,我們會(huì)保留這個(gè)issue,因?yàn)槲覀兪盏搅撕芏鄇ava 8的需求
上面已經(jīng)很肯定說明了,使用musl libc是運(yùn)行不了Oracle JDK的,至于他說的重新編譯不曉得啥時(shí)候去了,因?yàn)樗B源碼都拿不到。
下面還有一些其他的回答也看看
Then why are you trying to use that glibc package on Alpine? This is unofficial hack that is not supported by Alpine community. The only officially supported JRE/JDK are the mentioned openjdk packages built against musl libc.
## 你為啥要在alpine使用glibc庫(kù)呢,這是不受Alpine社區(qū)支持的非官方的庫(kù),官方唯一支持的就只有針對(duì)musl libc構(gòu)建的openjdk包。
## 有人提問
Our project is very complex and getting it running on OpenJDK would likely be very costly...
## 我們的項(xiàng)目非常復(fù)雜,如果改成運(yùn)行在OpenJDK可能代價(jià)非常大。
## 回答
Then you’re probably doing it wrong… Oracle JDK is just branded distribution of OpenJDK, the code base is nearly identical. That said, exceptions may exist, mainly in case of graphic Applications.
## 那你可能錯(cuò)了,Oracle JDK只是OpenJDK的一個(gè)發(fā)行版,代碼庫(kù)基本是一樣的,例外可能存在,主要是在圖形應(yīng)用程序的情況下(意思是應(yīng)該可以無(wú)縫遷移)
If you really need OracleJDK, then use some glibc-based distribution, not Alpine. Adding glibc to Alpine is not a stable production-quality solution.
## 如果你真的選擇OracleJDK,那使用一些基于glibc的發(fā)行版而不是使用Alpine,在Alpine中添加glibc庫(kù)并不是生產(chǎn)上完美的解決方案
# 繼續(xù)看別人提問
I hope alpine considers officially supporting oracle java in the future.
## 我希望alpine考慮在未來正式支持oracle java。
Once again. Oracle JDK is a proprietary product, they don’t provide source-code of all their modifications to OpenJDK and build system, just binaries. These binaries are build against glibc (GNU C Library). Alpine Linux doesn’t use glibc, it’s based on (much better) musl libc.
## 再解釋一遍,oracle jdk它是一個(gè)專屬產(chǎn)品,它在OpenJDK之上寫的源代碼不提供啊,就僅僅提供了一個(gè)二進(jìn)制文件還是基于glibc編譯的,Alpine不使用glibc,它是基于更小的musl libc
Glibc and musl libc are (partially) incompatible (mainly because glibc doesn’t comply with POSIX standards). Therefore software built against glibc may not work on musl libc without recompiling. This is the case of Oracle JDK. Because it’s a proprietary product, we can’t recompile it and there’s nothing we can do about it!
## Glibc和musl libc(部分)不兼容,主要是因?yàn)镚libc不符合POSIX標(biāo)準(zhǔn),所以基于glibc構(gòu)建的軟件如果不重新編譯就可能無(wú)法在musl libc上運(yùn)行(因?yàn)槟遣糠值牟患嫒荩@就是目前不支持OracleJDk的情況,OracleJDk它又是一個(gè)私有產(chǎn)品,我們拿不到源碼不能重新編譯,我們也無(wú)能為力呀。
libc is a very base system library, it’s not yet another library you can simply install along with others. Adding support for glibc would basically mean supporting another platform. The cost of this is too high. Also it doesn’t make much sense; Alpine with glibc would not be Alpine anymore! Alpine’s “motto” is: small, simply and secure. You can’t get this with glibc.
## glibc是一個(gè)非常底層的系統(tǒng)庫(kù),它還不是一個(gè)可以簡(jiǎn)單與其他庫(kù)一起安裝的庫(kù),添加對(duì)glibc的支持就意味著需要支持另一個(gè)平臺(tái),這樣做的代價(jià)太高,并且也沒啥太大意義。這樣做Alpine將不再是Alpine,Alpine的宗旨就是小,簡(jiǎn)單,安全,這是glibc做不到的。
這個(gè)jirutka不曉得是不是官方的大佬,感覺也要被氣死了,后面的還有很多就不都翻譯了,大家可以去看看大佬們對(duì)這個(gè)問題的爭(zhēng)論。下面我們還是看怎么強(qiáng)行在Alpine安裝OracleJDK吧。
安裝glibc
常規(guī)流程走不通,實(shí)在要用,那就只能是跟jirutka小哥說的一樣,讓他不再是一個(gè)Alpine了,安裝glibc
安裝key
## 下載key,以前用的這個(gè)地址現(xiàn)在好像訪問不了了,可以換一個(gè)地址
~ # wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://raw.Githubusercontent.com/sgerrand/alpine-pkg-glibc/master/sgerrand.rsa.pub
wget: server returned error: HTTP/1.1 404 Not Found
## 上面那個(gè)用不了就用這個(gè)
~ # wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub
## 查看key
cat /etc/apk/keys/sgerrand.rsa.pub
下載glibc.apk包,自己指定需要版本,可能有點(diǎn)慢,大家可以想辦法下載然后上傳也行
wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.29-r0/glibc-2.29-r0.apk
我這邊是在外面下載了一個(gè)上傳,然后copy到容器內(nèi)
[root@node01 ~]# docker cp glibc-2.29-r0.apk alpine:/root
安裝
~ # apk add glibc-2.29-r0.apk --no.NETwork
(1/1) Installing glibc (2.29-r0)
OK: 13 MiB in 16 packages
安裝成功后再usr目錄下會(huì)多出一個(gè)glibc-compat目錄
~ # cd /usr/
/usr # ls
bin glibc-compat lib local sbin share
查看/lib64/下的軟鏈接發(fā)現(xiàn)自動(dòng)連接到了/usr/glibc-compat/lib/ld-linux-x86-64.so.2
/usr # cd /lib64/
/lib64 # ls -l
total 0
lrwxrwxrwx 1 root root 42 Dec 6 19:34 ld-linux-x86-64.so.2 -> /usr/glibc-compat/lib/ld-linux-x86-64.so.2
再次查看java版本,可以正常使用了
~ # /usr/local/share/java/jdk/bin/java -version
java version "1.8.0_231"
Java(TM) SE Runtime Environment (build 1.8.0_231-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.231-b11, mixed mode)
JDK雖然是使用正常了,但是有的東西就不正常了,上篇文章我特意使用cronolog舉了一些例子。現(xiàn)在來看看cronolog還能正常使用不
查看現(xiàn)在的時(shí)區(qū),
~ # date
Sun July 2 20:02:20 CST 2023
## 按小時(shí)生成日志文件
~ # while true; do echo 'test...';sleep 1;done| cronolog /root/test-%m%d%H.log
## 生成文件120612 現(xiàn)在明明是20點(diǎn)怎么生成的是12點(diǎn)
~ # ls
glibc-2.29-r0.apk test-120612.log tzdata
咋回事,時(shí)區(qū)明明是對(duì)的,但是cronolog切割日志出問題了,這明顯少了八個(gè)小時(shí)呀。上篇文章我們是軟鏈接到/lib目錄。改回去看看
## 修改動(dòng)態(tài)庫(kù)軟連接
ln -snf /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2
## 按小時(shí)生成日志文件
while true; do echo 'test...';sleep 1;done| cronolog /root/test-%m%d%H.log
## 正常生成
~ # ls
glibc-2.29-r0.apk test-120612.log test-120620.log tzdata
## 但是改回去jdk就不可用了,還是改回來吧
ln -snf /usr/glibc-compat/lib/ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2
這明顯是glibc少了時(shí)區(qū),看看glibc下有沒有時(shí)區(qū)補(bǔ)丁,發(fā)現(xiàn)目前最新版本只有i18n等一些補(bǔ)丁,并沒有zoneinfo
https://github.com/sgerrand/alpine-pkg-glibc/releases
解決辦法
將cronolog源碼下載下來,再alpine中編譯一版。編譯前提需要安裝gcc,g++,make庫(kù),編譯好后在驗(yàn)證無(wú)問題。如果其他二進(jìn)制文件再Alpine使用了glibc庫(kù)后也有類似問題,可以使用此方法在Alpine中編譯一版。